【问题标题】:Can I create a dynamic table-valued function on SQL Server?我可以在 SQL Server 上创建动态表值函数吗?
【发布时间】:2019-11-26 12:19:46
【问题描述】:

我正在尝试在 SQL 中编写一个函数,该函数应该返回一个表,该表是模式中所有表的联合。这可以在 SQL Server 中执行吗?

我经常需要在一个模式中连接表,为此我从这里找到了一个非常好的动态查询:

How to SELECT and UNION from a group of Tables in the schema in SQL Server 2008 R2

(MarkD的回答)

现在,因为我需要在不同的架构上重复执行此操作。我正在考虑编写一个函数,它将模式名称和通配符作为表名的输入,并输出所有表的联合。

但是,我担心在构造 create 函数时可能需要声明表列 - 我不能这样做,因为表应该是动态的!

我对 SQL 函数并不完全熟悉,我希望我可以像在 Python 中那样做这件事。这可能吗?

CREATE FUNCTION udfJoinTablesinSchema
     (@Schemaname VARCHAR(100), 
      @TableNameWildcard VARCHAR(100))
RETURNS TABLE
AS
     RETURN 
        (DECLARE @SelectClause VARCHAR(100) = 'SELECT *',
                 @Query NVARCHAR(MAX)   = '' 

         SELECT @Query = @Query + @SelectClause + ' FROM ' + TABLE_SCHEMA+'.['+TABLE_NAME + '] UNION ALL '
         FROM INFORMATION_SCHEMA.TABLES
         WHERE TABLE_NAME like @TableNameWildcard
          AND TABLE_SCHEMA = @Schemaname 

         SELECT @Query = LEFT(@Query, LEN(@Query) - LEN(' UNION ALL '))

         PRINT(@Query)
         EXEC(@Query)
        );

我收到一条错误消息:

“DECLARE”附近的语法不正确。当我将鼠标悬停在 DECLARE 上时,期待 '('、SELECT 或 WITH。"。

它还抱怨两个标量变量@TableNameWildCard@Schemaname

【问题讨论】:

  • 您不能在 SQL Server 的用户定义函数中使用动态 SQL。
  • @ZoharPeled 说了什么。但是您可以使用存储过程来做到这一点。
  • 你应该使用'...' + QUOTENAME(TABLE_NAME) + '...'而不是'...['+TABLE_NAME + ']...'。就像用于注入 WHERE 的字符串一样,用于注入对象的字符串也可能遭受注入攻击。
  • 如果你的表在所有地方都具有相同的结构,我会说查找查询不是问题。多个相同的表非常清楚地表明设计是这里的真正问题。这种事情几乎总是使用一个额外的列来标识“类型”而不是几十个相同的表更好。
  • 另外,错误的原因是因为您已将函数声明为内联表值函数,但将其编写为多行表值函数。后者的表现确实很差,但是,即使您可以在函数中使用动态 SQL,也不可能为此编写一个 tvf 作为内联的。幸运的是你不能,我想。

标签: sql sql-server function tsql dynamic


【解决方案1】:

没有


这是 SQL Server 中的明确限制。存储过程可以更改表数据,而user-defined functions 则不能。

虽然动态 SQL 不需要更改表数据,但它确实需要存储过程调用。由于存储过程允许更改数据,它不能在表值函数中使用。

使用存储过程是解决问题的一种可能方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-30
    • 2015-08-14
    • 2014-09-14
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    相关资源
    最近更新 更多