1

我正在尝试编写一个脚本,该脚本可用于在我们的合并复制快照代理完成将快照应用于订阅者后恢复对存储过程的权限。这个 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

两个问题:

  1. 如何为临时表中的每个项目执行上述脚本?

  2. 应用快照后,是否有更好的编写脚本来恢复数据库中每个存储过程的权限的方法(注意:我必须能够使用 SQL 系统表来提取存储过程名称)?

4

3 回答 3

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
于 2012-10-26T15:30:35.333 回答
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
于 2012-10-26T15:29:28.410 回答
0

@010001100110000101110010011010 和 @podiluska 打败了我,但是......

SELECT COUNT(*) FROM sqltemp

在此之外:

SET @end = SELECT COUNT(*) FROM sqltemp
WHILE (@counter < @end)
    ...

无需为每次循环迭代重新计算结束条件。

于 2012-10-26T15:35:43.100 回答