使用MS Sql Server
我正在执行以下代码:
SELECT @Fieldname = COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TableName
AND ORDINAL_POSITION = @FIELD
它将 IsPrimary 分配给@Fieldname,这是预期的答案。但是当我执行这一行时:
SET @MyField = (SELECT @Fieldname FROM inserted WHERE FileID = @FileID)
@MyField也被赋值 IsPrimary ,而不是1,IsPrimary字段中包含的值。
(注意:执行SELECT IsPrimary FROM插入WHERE FileID = @FileID正常工作并返回预期值1)
什么是正确的sql语句?
答案 0 :(得分:1)
它不会那样工作。您不能使用变量来表示查询的部分内容。
但是,您可以将查询字符串动态构建到VARCHAR
变量中,并使用EXEC
函数执行它。它伴随着各种权衡(不同的安全上下文,sql注入攻击的风险等等),但它会按照你期望的方式工作。
答案 1 :(得分:0)
详细说明Crono的答案,并修复我之前的答案,“正确的(T-)SQL语句”将是这样的:
SELECT FileID = CAST(1 AS int), CreatedAt = GETDATE()
INTO #inserted;
DECLARE @Fieldname varchar(30),
@MyField datetime,
@FileID int,
@sql nvarchar(4000);
SELECT @Fieldname = 'CreatedAt',
@FileID = 1;
SELECT @sql = 'SELECT @MyField = ' + @Fieldname + ' FROM #inserted WHERE FileID = ' + CAST(@FileID AS varchar) + ';';
EXEC sp_executesql @sql, N'@MyField datetime OUTPUT', @MyField OUTPUT;
SELECT [@MyField] = @MyField;
DROP TABLE #inserted;
我添加了代码来创建临时表#inserted
,这样您就可以按原样运行示例代码。
我很高兴我在下面提到了Erland的文章,因为它提出了一些关于动态SQL的重要内容,这解释了为什么我以前的答案不起作用:
在动态SQL块中,您无法访问本地变量(包括表变量)或调用存储过程的参数。但是,如果使用sp_executesql,则可以将参数(in和out)传递给动态SQL块。
请参阅Erland Sommarskog的(经典)The Curse and Blessings of Dynamic SQL,了解有关使用动态SQL(即生成SQL然后执行它)的更多信息的加载。