4

我想创建一个 SQL 表值函数,它将通过我的 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

请提出正确的方法!

4

3 回答 3

4

试试这个——

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
于 2013-07-19T07:23:32.463 回答
3

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

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

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

首先,这会对您的数据库性能产生负面影响。请在 EXEC() 和 sp_executesql() 上阅读此内容。我希望不会从应用程序的多个部分调用您的 SP,因为这会给您带来麻烦,至少在性能方面。

另一件事是——你是如何以及在哪里构建你的 SQL 的?显然,您在其他地方执行此操作,并且似乎是手动创建的。如果我们谈论的是现代应用程序,那么有很多 OR/M 解决方案可以解决这个问题,如果可能的话,应该始终避免在运行时手动构建 TSQL。更不用说 EXEC 并不能保护您免受任何形式的 SQL 注入攻击。但是,如果所有这些都是某些数据库管理 TSQL 捆绑包的一部分,那么请忘记他的段落。

最后,如果您想简单地从某个现有表(或其中的一部分)加载新表作为 TSQL 中某些管理任务的一部分,请考虑发出 SELECT ... INTO ... 这将创建一个新目标为您提供表结构(省略索引和约束)并复制数据。SELECT INTO 将优于 INSERT INTO SELECT,因为SELECT INTO 得到最低限度的记录

我希望这会让你(和其他人)至少走上正轨。

于 2013-07-19T08:16:22.373 回答
-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
于 2013-07-19T07:44:16.177 回答