【问题标题】:Dynamic union of table if a certain field exists如果某个字段存在,则表的动态联合
【发布时间】:2019-09-06 16:38:21
【问题描述】:

我正在尝试在具有某些字段(在我的示例 field1 和 field2 中)的表上构建一个动态联合。工会已经在工作,但在任何桌子上。现在我只需要包含具有 field1 和 field2 的那些。

DECLARE @SQL VARCHAR(max)

SET @SQL = ''

SELECT @SQL = @SQL + CASE Len(@SQL) WHEN 0 THEN '' ELSE ' UNION ALL ' END
+ ' SELECT [field1], [field2] FROM dbo.['
+ NAME + ']'
FROM   sys.tables
WHERE  NAME LIKE 'CUST_TABLE%'

EXEC (@SQL)

我想我需要以某种方式组合这个查询:

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE   TABLE_NAME like 'CUST_TABLE%'
and COLUMN_NAME='field1'

【问题讨论】:

  • ,而不是字段...
  • 和 COLUMN_NAME IN ('field1', 'field2')
  • 小心,'[' + NAME + ']' 并不安全(无注入 SQL)。使用QUOTENAME
  • @Larnu:不过,系统表sys.tables 包含一行带有name 的行可能会导致某些查询的from 子句中的括号内出现havov。我认为我们很容易忽略这种可能性。
  • 你这么说,@ThorstenKettner,但这并没有改变我(可能还有你自己)已经看到至少一个例子,其中用户在这里提出问题的对象名称中有 ] ;它发生的可能性(多么小)也不意味着您应该使用不良做法。就像 int 值永远不能用于注入动态语句并不意味着它应该被注入。它仍应使用sp_executesql正确进行参数化。仅当您“认为”没问题时才忽略良好/正确的做法,最终只会导致您在不正确时这样做。

标签: sql sql-server


【解决方案1】:

你很接近。查询视图INFORMATION_SCHEMA.COLUMNS。聚合每个表名,并通过在 HAVING 子句中计算它们来确保表的两列都存在。

DECLARE @SQL VARCHAR(max)

SET @SQL = ''

SELECT @SQL = @SQL + CASE Len(@SQL) WHEN 0 THEN '' ELSE ' UNION ALL ' END
                   + ' SELECT [field1], [field2] FROM dbo.[' + table_name + ']'
FROM   information_schema.columns
WHERE  table_name LIKE 'CUST_TABLE%'
GROUP BY table_name
HAVING COUNT(CASE WHEN COLUMN_NAME = 'FIELD1' THEN 1 END) > 0
   AND COUNT(CASE WHEN COLUMN_NAME = 'FIELD2' THEN 1 END) > 0

EXEC (@SQL)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 2012-04-22
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多