我正在尝试编写一个脚本,在我们的合并复制快照代理完成将快照应用于订阅者之后,该脚本可用于恢复存储过程的权限。这个SQL需要有点动态。
目前,我正在选择所有存储过程的列表,并将它们与“授予”权限的字符串语句一起插入临时表中。我试图遍历该表上的所有行,使用EXEC()命令逐个执行语句。我一直收到错误
当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式
但我的SQL语句看起来应该没问题。也许我不明白WHILE在SQL Server中是如何工作的。
这是我的代码:
BEGIN
CREATE TABLE sqltemp (id int IDENTITY(1, 1) , Stmt1 varchar(max), Stmt2 varchar(max), Stmt3 varchar(max))
INSERT INTO sqltemp
SELECT
'GRANT EXECUTE ON OBJECT::' as Stmt1, name as Stmt2, 'TO edoc_only_execute' as Stmt3
FROM sys.sysobjects
WHERE
type = 'P' AND name NOT LIKE 'MSMerge%'
DECLARE @counter int = 1
WHILE (@counter < (SELECT COUNT(*) FROM sqltemp))
BEGIN
DECLARE @sqlrun varchar(max)
SET @sqlrun = (SELECT Stmt1, Stmt2, Stmt3 FROM sqltemp WHERE id = @counter)
EXEC(@sqlrun)
SET @counter = @counter + 1
END
END
GO
DROP TABLE sqltemp
两个问题:
如何为临时表中的每个项目完成上述脚本的执行?
在应用快照后,是否有更好的方法来编写脚本来恢复数据库中每个存储过程的权限(注意:我必须能够使用SQL系统表来提取存储过程名称)?
答案 0 :(得分:3)
你不能说
SET @sqlrun = (SELECT Stmt1, Stmt2, Stmt3 FROM sqltemp WHERE id = @counter)
你必须连接它们
SELECT @sqlrun = Stmt1 +' '+ Stmt2 +' '+ Stmt3 FROM sqltemp WHERE id = @counter
更好的解决方案可能是?
GRANT EXEC TO edoc_only_execute
答案 1 :(得分:2)
更正了第一个问题的查询
BEGIN
CREATE TABLE sqltemp (id int IDENTITY(1, 1) , Stmt1 varchar(max), Stmt2 varchar(max), Stmt3 varchar(max))
INSERT INTO sqltemp SELECT 'GRANT EXECUTE ON OBJECT::' as Stmt1, name as Stmt2, 'TO edoc_only_execute' as Stmt3
FROM sys.sysobjects
WHERE type = 'P' AND name NOT LIKE 'MSMerge%'
DECLARE @counter int = 1
WHILE (@counter < (SELECT COUNT(*) FROM sqltemp))
BEGIN
DECLARE @sqlrun varchar(max)
SELECT @sqlrun = Stmt1 + Stmt2 +' '+ Stmt3 FROM sqltemp WHERE id = @counter
PRINT @sqlrun
EXEC(@sqlrun)
SET @counter = @counter + 1
END
END
答案 2 :(得分:0)
@ 010001100110000101110010011010和@podiluska打败了我,但是......
SELECT COUNT(*) FROM sqltemp
在外面:
SET @end = SELECT COUNT(*) FROM sqltemp
WHILE (@counter < @end)
...
无需为每个循环迭代重新计算结束条件。