我有一个应该更新两个表的存储过程,其定义如下
CREATE procedure ChangeNames
@oldname nvarchar(100),
@newname nvarchar(100),
@tablename nvarchar(100)
AS
Begin
Declare @sql nvarchar(max);
Set @sql = 'UPDATE' + @tablename + 'SET NAMES =' + @newname + 'where
names =' + @oldname +
'UPDATE ref_names SET NAMES =' + @newname + 'where names =' + @oldname
Execute sp_executesql @sql
End`
然后我执行以下过程:
USE [database_name]
GO
exec dbo.ChangeNames
@oldname = 'ab',
@newname = 'cd',
@tablename = 'ef'
GO
我收到以下错误:
'='附近的语法不正确。
我该如何解决?
答案 0 :(得分:2)
在分隔文字值时,关键字和单引号之间缺少一些空格:
Set @sql = '
UPDATE ' + @tablename + ' SET
NAMES = ''' + @newname + '''
WHERE
names = ''' + @oldname + '''
UPDATE ref_names SET
NAMES = ''' + @newname + '''
WHERE
names = ''' + @oldname + ''''
建议在执行动态SQL之前使用PRINT
检查生成的SQL,您将能够发现这些错误。
PRINT (@sql)
-- Execute sp_executesql @sql
还要将QUOTENAME
添加到对象名称,例如动态表引用。对象名称可能包含破坏动态SQL的字符,例如空格。使用QUOTENAME
可以正确地将它们转义。
Set @sql = 'UPDATE ' + QUOTENAME(@tablename) + --...
最后一件事,请确保传递给搜索和更新的值转义了单引号,否则它们还会破坏动态SQL。
因此,如果要将值更新为FLIGHT CENTRE's TRAVEL GROUP
(请注意中间的单引号),则必须实际编写FLIGHT CENTRE''s TRAVEL GROUP
,以便正确地将引号转义。
答案 1 :(得分:2)
我会参数化您的SQL,而不是串联值,并引用动态对象名称。它变得更加安全:
CREATE PROCEDURE ChangeNames @oldname nvarchar(100),
@newname nvarchar(100),
@tablename sysname --changed to sysname, as that's the appropriate datatype for an object's name
AS
BEGIN
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'UPDATE ' + QUOTENAME(@tablename) + NCHAR(10) +
N'SET names = @New' + NCHAR(10) +
N'WHERE names = @old;' + NCHAR(10) +
N'UPDATE ref_names' + NCHAR(10) +
N'SET names = @New' + NCHAR(10) +
N'WHERE names = @old;';
PRINT @SQL; --Your best friend
EXEC sp_executesql @SQL, N'@new nvarchar(100), @old nvarchar(100)', @new = @newname, @old = @oldname;
END
答案 2 :(得分:0)
更新关键字后您缺少空格
Set @sql = 'UPDATE ' + @tablename + 'SET NAMES =' + @newname + 'where