我正在尝试编写一个过程来更快地从任何表中删除Unique约束。
IF EXISTS
(SELECT *
FROM dbo.sysobjects
WHERE id = object_id(N'[dba].[spu_drop_uq_index]'))
DROP PROCEDURE [dba].[spu_drop_uq_index]
GO
CREATE PROCEDURE [dba].[spu_drop_uq_index] (@table varchar(1000), @index varchar(1000))
AS
BEGIN
DECLARE @sql varchar(1000)
SET @sql = 'ALTER TABLE ['+@table+'] DROP CONSTRAINT ['+@index+']'
IF EXISTS (SELECT name FROM sysindexes WHERE name = @index)
EXEC @sql
END
GO
EXEC [dba].[spu_drop_uq_index] @table = 'aaa', @index = 'UQ_xxx'
GO
但是我收到了一个错误:
The name 'ALTER TABLE [aaa] DROP CONSTRAINT [UQ_xxx]' is not a valid identifier.
但是,如果我不动态执行此操作,则会成功:
ALTER TABLE [aaa] DROP CONSTRAINT [UQ_xxx]
我做错了什么? :)谢谢!
答案 0 :(得分:3)
使用
exec sp_executesql @sql
而不是EXEC
,或将@sql
放在括号中
Exec (@sql)
sp_executesql
是首选:http://msdn.microsoft.com/en-us/library/ms175170(v=sql.105).aspx
要执行字符串,建议您使用sp_executesql存储过程而不是EXECUTE语句。因为这个存储过程支持参数替换,所以sp_executesql比EXECUTE更通用;并且因为sp_executesql生成更有可能被SQL Server重用的执行计划,所以sp_executesql比EXECUTE更有效。
答案 1 :(得分:1)
将exec字符串包装在括号中:
EXEC (@sql)
执行动态字符串时,需要括号。执行sprocs时,它们不是。