SQL Server 查询中的动态表名和变量名

Posted

技术标签:

【中文标题】SQL Server 查询中的动态表名和变量名【英文标题】:Dynamic table name and variable name in query in SQL Server 【发布时间】:2018-08-10 10:38:49 【问题描述】:

我正在尝试使用动态表名和日期从 Python 运行查询。在此过程中,我在 SSMS 中尝试了以下查询,但它产生了错误消息。如何将变量用于表名和日期,并让查询正常工作?

DECLARE @table_name VARCHAR(50)='table_name';
DECLARE @valid_to datetime = getdate();

EXEC('UPDATE '+ @table_name + '
SET valid_flag = 0, 
valid_to = '+ @valid_to +'
where valid_flag=1')

我收到以下错误消息:

消息 102,第 15 级,状态 1,第 3 行 '10' 附近的语法不正确

【问题讨论】:

UPDATE 后面少了一个空格。 除了许多其他缺陷之外,这很明显来自这里:valid_to = '+ @valid_to +'。您的@valid_to 被声明为datetime,并且不能成为+ 字符串连接的一部分。但是CAST 不能解决这个问题(日期格式、引号......)正确的解决方案来自 Gordon:使用参数并使用QUOTENAME()! (或meet bobby tables) 【参考方案1】:

使用sp_executesql和参数:

DECLARE @table_name VARCHAR(50) = 'table_name';
DECLARE @valid_to datetime = getdate();

DECLARE @sql NVARCHAR(max) = N'
UPDATE '+ @table_name + N'
    SET valid_flag = 0, 
        valid_to = @valid_to
    WHERE valid_flag = 1
';

EXEC sp_executesql @sql, N'@valid_to datetime', @valid_to=@valid_to;

编辑:

根据 Larnu 的推荐评论:

DECLARE @table_name sysname = 'table_name';
DECLARE @valid_to datetime = getdate();

DECLARE @sql NVARCHAR(max) = N'
UPDATE '+ QUOTENAME(@table_name) + N'
    SET valid_flag = 0, 
        valid_to = @valid_to
    WHERE valid_flag = 1
';

EXEC sp_executesql @sql, N'@valid_to datetime', @valid_to=@valid_to;

【讨论】:

我建议 sysname 超过 varchar(50),以防 OP 确实有一个名称更长的对象。您绝对应该使用QUOTENAME,但 SQL 注入不是您的朋友。但至少 WHERE 是参数化的。

以上是关于SQL Server 查询中的动态表名和变量名的主要内容,如果未能解决你的问题,请参考以下文章

sql server 用变量定义表名,能够查询

mybatis动态调用表名和字段名

使用SQL Server和Mysql查询所有数据库名表名和字段名

sqlserver 如何获得所有数据库名 如何获得已知数据库所有表名 和 已知表明获得所有字段名和字段类型

sql server2008如何查询在指定的数据库中所有的表名和每个表的字段名及字段类型

SQL Server:使用动态表名插入存储过程