【问题标题】:SQL Server 2012 - Dynamic SQLSQL Server 2012 - 动态 SQL
【发布时间】:2015-06-02 11:10:16
【问题描述】:

有人可以解释一下为什么下面的查询有效吗?我假设第一个 DECLARE 使用足够长的 VARCHAR 来保存表名。但是为什么第二个 DECLARE 使用 VARCHAR 以及为什么它的相应查询需要包含在“引号”中?

USE Northwind

DECLARE @TableName VARCHAR(25)=
  (Select top 1 tab.name
  From Sys.tables tab
  Where name not like 'dtproperties'
  and name not like 'sysdiagrams'
  order by tab.name asc)

DECLARE @Output VARCHAR(100) =
  'SELECT COUNT(*) AS [CountOf_' + @TABLENAME + ']
   FROM [' + @TABLENAME + ']'

EXEC(@Output)

【问题讨论】:

  • 你也应该非常小心这个查询。它没有正确转义。
  • @Output 的值是 varchar (text/string) 的类型,所以需要用引号括起来。
  • 第一个声明语句只是将字符串值设置为“表名”,这就像从另一个变量中分配一个变量一样。第二个声明语句就像为变量“输出”分配常量或文字值一样。所以它应该用引号括起来..

标签: sql-server sql-server-2012 dynamic-sql


【解决方案1】:
  1. @TableName 的数据类型为 VARCHAR(25) 不正确(或至少是一个糟糕的选择)。大多数对象(表、视图、存储过程、函数等)的数据类型为sysname,它是NVARCHAR(128) 的别名。所以不,第一个 DECLARE 使用的数据类型不仅 不够 足够长,而且也无法容纳大量其他有效的 Unicode 字符。

  2. 第二个 DECLARE 使用 VARCHAR(100),因为它做了两个可能错误的假设:

    1. 永远不会有任何 Unicode 字符,并且
    2. 表的名称长度永远不会超过 62 个字符(这是删除该查询中显示的其余字符后剩下的字符数)
  3. 查询用引号括起来并通过EXEC() 提交(即它是动态 SQL),因为查询的列和表都不能是变量。

【讨论】:

  • 谢谢!您的回答几乎涵盖了它!
最近更新 更多