1

マージ レプリケーション スナップショット エージェントがサブスクライバーへのスナップショットの適用を完了した後、ストアド プロシージャへのアクセス許可を復元するために使用できるスクリプトを作成しようとしています。この SQL はある程度動的である必要があります。

現在、すべてのストアド プロシージャのリストを選択し、それらを「許可」権限の文字列ステートメントと共に一時テーブルに挿入しています。そのテーブルのすべての行をループして、EXEC() コマンドを使用してステートメントを 1 つずつ実行しようとしています。エラーが発生し続けます

サブクエリが EXISTS で導入されていない場合、選択リストに指定できる式は 1 つだけです。

しかし、私のSQLステートメントは問題ないように見えます。SQL Server で WHILE がどのように機能するかを理解していない可能性があります。

これが私のコードです:

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

2 つの質問:

  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 に答える