我想创建一个SQL tabled-value函数,它将通过我的API接收查询作为n参数。在我的函数中,我想执行该查询。查询将是SELECT语句。
这是我到目前为止所做的以及要实现的目标,但这不是正确的方法。
CREATE FUNCTION CUSTOM_EXPORT_RESULTS (
@query varchar(max),
@guid uniqueidentifier,
@tableName varchar(200))
RETURNS TABLE
AS
RETURN
(
-- Execute query into a table
SELECT *
INTO @tableName
FROM (
EXEC(@query)
)
)
GO
请建议正确的方法!
答案 0 :(得分:3)
试试这个 -
CREATE PROCEDURE dbo.sp_CUSTOM_EXPORT_RESULTS
@query NVARCHAR(MAX) = 'SELECT * FROM dbo.test'
, @guid UNIQUEIDENTIFIER
, @tableName VARCHAR(200) = 'test2'
AS BEGIN
SELECT @query =
REPLACE(@query,
'FROM',
'INTO [' + @tableName + '] FROM')
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = '
IF OBJECT_ID (N''' + @tableName + ''') IS NOT NULL
DROP TABLE [' + @tableName + ']
' + @query
PRINT @SQL
EXEC sys.sp_executesql @SQL
RETURN 0
END
GO
输出 -
IF OBJECT_ID (N'test2') IS NOT NULL
DROP TABLE [test2]
SELECT * INTO [test2] FROM dbo.test
答案 1 :(得分:3)
我在你的问题中看到的是封装:
为什么要进行这样的封装?
首先,这会对您的数据库性能产生负面影响。请阅读this on EXEC() and sp_executesql()。我希望您的SP不会从您的应用程序的多个部分调用,因为这会让您陷入困境,至少在性能方面。
另一件事是 - 你如何以及在哪里构建SQL?显然你是在其他地方做的,似乎是手动创建的。如果我们谈论的是当代应用程序,那么有很多OR / M解决方案,如果可能的话,应该始终避免在运行时手动构建TSQL。更不用说EXEC不会防止任何形式的SQL注入攻击。但是,如果所有这些都是某些数据库管理TSQL包的一部分,请忘记他的段落。
最后,如果您只想从一些现有表(或部分表)中加载一个新表作为TSQL中某个管理任务的一部分,请考虑发出SELECT ... INTO ...这将创建为您创建新的目标表结构(省略索引和约束)并复制数据。 SELECT INTO将优于INSERT INTO SELECT,因为SELECT INTO gets minimally logged。
我希望这会让你(和其他人)至少走上正轨。
答案 2 :(得分:-5)
您也可以使用存储过程,这是您可以尝试的代码。
CREATE FUNCTION CUSTOM_EXPORT_RESULTS
(
@query varchar(max),
@guid uniqueidentifier,
@tableName varchar(200)
)
RETURNS TABLE
AS
RETURN
(
declare @strQuery nvarchar(max)
-- Execute query into a table
SET @strQuery = REPLACE(@query,'FROM', 'INTO '+@tableName+' FROM')
exec sp_executesql @strQuery
)
GO