(由于问题中不明显的原因,我假设您需要动态 SQL,因为这似乎根本不需要动态 SQL。)
正如@Gidil 建议的那样,这里的问题是试图将唯一标识符视为字符串。在这种情况下,实际上没有任何理由NEWID()
在外部范围内声明,因为您可以简单地说:
SET @query = 'INSERT ... VALUES(NEWID(), 28);';
PRINT @query;
现在,您应该将其NVARCHAR(MAX)
用作参数,因为最终您应该使用sp_executesql
而不是EXEC()
执行此操作。
如果您需要文字,可以将引号加倍:
DECLARE @string VARCHAR(32);
SET @string = 'foo';
SET @query = N'INSERT ... VALUES(''' + @string + ''', 28);';
但是我发现使用起来更具可读性CHAR(39)
:
SET @query = N'INSERT ... VALUES(' + CHAR(39) + @string + CHAR(39) + ', 28);';
更好的是无论如何都不要将这些变量附加到字符串中。您应该尽可能使用正确键入的参数。
DECLARE @query NVARCHAR(MAX);
DECLARE @string VARCHAR(32), @newid UNIQUEIDENTIFIER, @id INT;
SELECT @string = 'foo', @newid = NEWID(), @id = 28;
SET @query = N'INSERT ... VALUES(@string, @newid, @id);';
EXEC sp_executesql @query,
N'@string VARCHAR(32), @newid UNIQUEIDENTIFIER, @id INT',
@string, @newid, @id;
当然,它更笨重,但它比 SQL 注入更安全,它让你不再试图找出和处理将单引号嵌入字符串的麻烦......