将查询作为参数发送到SQL函数

时间:2013-07-19 06:52:19

标签: sql sql-server

我想创建一个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

请建议正确的方法!

3 个答案:

答案 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)

我在你的问题中看到的是封装:

  • 采用动态SQL表达式
  • 执行它以填充参数化表格

为什么要进行这样的封装?

首先,这会对您的数据库性能产生负面影响。请阅读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