如何在动态 SQL 中转义单引号
How do I escape a single quote in dynamic SQL
我在 SQL 服务器上有以下查询,一些值存储在之前计算的变量中:
SET @Command = N'INSERT INTO Products (Id
,Region
,Name
,Category
,CreatedBy
,CreatedOn
,) SELECT ' + @Id + ',
Region,
''' + @ProductName + ''',
Category,
CreatedBy,
CreatedOn FROM ' + @ProductTable + '
WITH (NOLOCK) WHERE Id IS NOT NULL';
EXEC(@Command)
运行正常,除非 @ProductName
的值包含引号(例如 Jim's Product),在这种情况下我会收到以下错误:
Unclosed quotation mark after the character string
有没有办法在这样的动态查询中处理变量中的单引号,其中插入的选定值之一(@ProductName
在这种情况下)直接是要插入的值而不是源上的实际列名称 table 需要检索其值以进行插入?
最好的方法是使用 sp_executesql
而不是 EXEC
并为 @ProductName
值使用适当的参数。
无法参数化的查询的其余部分(table @ProductTable
的名称)将保持动态字符串连接。
在这种情况下,您不需要转义任何内容,并且可以防止 SQL 注入。
像这样:
SET @Command =
N'INSERT INTO Products
(Id
,Region
,Name
,Category
,CreatedBy
,CreatedOn)
SELECT
@ParamId
,Region
,@ParamProductName
,Category
,CreatedBy
,CreatedOn
FROM ' + @ProductTable + N' WITH (NOLOCK)
WHERE ID IS NOT NULL'
;
EXEC sp_executesql
@Command
,N'@ParamId int, @ParamProductName nvarchar(255)'
,@ParamId = @Id
,@ParamProductName = @ProductName
;
我在 SQL 服务器上有以下查询,一些值存储在之前计算的变量中:
SET @Command = N'INSERT INTO Products (Id
,Region
,Name
,Category
,CreatedBy
,CreatedOn
,) SELECT ' + @Id + ',
Region,
''' + @ProductName + ''',
Category,
CreatedBy,
CreatedOn FROM ' + @ProductTable + '
WITH (NOLOCK) WHERE Id IS NOT NULL';
EXEC(@Command)
运行正常,除非 @ProductName
的值包含引号(例如 Jim's Product),在这种情况下我会收到以下错误:
Unclosed quotation mark after the character string
有没有办法在这样的动态查询中处理变量中的单引号,其中插入的选定值之一(@ProductName
在这种情况下)直接是要插入的值而不是源上的实际列名称 table 需要检索其值以进行插入?
最好的方法是使用 sp_executesql
而不是 EXEC
并为 @ProductName
值使用适当的参数。
无法参数化的查询的其余部分(table @ProductTable
的名称)将保持动态字符串连接。
在这种情况下,您不需要转义任何内容,并且可以防止 SQL 注入。
像这样:
SET @Command =
N'INSERT INTO Products
(Id
,Region
,Name
,Category
,CreatedBy
,CreatedOn)
SELECT
@ParamId
,Region
,@ParamProductName
,Category
,CreatedBy
,CreatedOn
FROM ' + @ProductTable + N' WITH (NOLOCK)
WHERE ID IS NOT NULL'
;
EXEC sp_executesql
@Command
,N'@ParamId int, @ParamProductName nvarchar(255)'
,@ParamId = @Id
,@ParamProductName = @ProductName
;