web-dev-qa-db-ja.com

データベース上のすべてのストアドプロシージャを変更するスクリプト

何千ものストアドプロシージャを含むデータベースがあり、何百ものストアドプロシージャを変更する必要があります。

それをより速くするために、すべてのストアドプロシージャを実行し、最初にコードを追加する(必要な場合)スクリプトを作成する方法を考えました。

たとえば、存在しない場合にSET NOCOUNT ONを追加するスクリプトを記述します。そのため、まだ持っていないすべてのストアドプロシージャが変更されます。

可能ですか?はいの場合、いくつかのヒント、ガイドを教えていただけますか?

私はそれをする方向性がないので、まだ何も試していません。

ありがとう。

解決済み

Tpetの提案のおかげで解決しました。多分最善の方法ではないかもしれません。コードを追加して、より安全にする必要があります。

DECLARE @HelpText TABLE
(
    Val NVARCHAR(MAX)
);

DECLARE @sp_names TABLE
(
    ID INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(128)
);

DECLARE @sp_count INT,
        @count INT = 0,
        @sp_name NVARCHAR(128),
        @text NVARCHAR(MAX);

INSERT  @sp_names
SELECT  name
FROM    sys.Procedures;

SET @sp_count = (SELECT COUNT(1) FROM sys.Procedures);

WHILE (@sp_count > @count)
BEGIN
    SET @count = @count + 1;
    SET @text = N'';

    SET @sp_name = (SELECT  name
                    FROM    @sp_names
                    WHERE   ID = @count);

    INSERT INTO @HelpText
    EXEC sp_HelpText @sp_name;

    SELECT  @text = COALESCE(@text + ' ' + Val, Val)
    FROM    @HelpText;

    DELETE FROM @HelpText;

    IF @text LIKE '%SET NOCOUNT ON%'
    BEGIN
        SELECT @text;
    END
    ELSE --Not found, should be added.
    BEGIN
        SET @text = REPLACE(@text, 'CREATE PROCEDURE', 'ALTER PROCEDURE');

        DECLARE @Find NVARCHAR(255);
        SET @Find = 'BEGIN';

        SET @text = STUFF(@text, CHARINDEX(@Find, @text), LEN(@Find), @Find + CHAR(13) + CHAR(10) + SPACE(4) + 'SET NOCOUNT ON;');

        EXECUTE sp_executesql @text;
    END
END
3
Misha Zaslavsky

sys.proceduresからすべての手順を取得することから始めます

SELECT  * FROM sys.Procedures 

次に、それぞれにEXEC sp_helptextを使用して、プロシージャのテキストをロードします。

追加するテキストを検索し、必要に応じて追加し、

次に、更新されたテキストを変数にロードし、動的に実行します。

4
tpet

上記の@tpetからの回答は適切です。

@Davidからのコメントごとに、定義をもう少し明確に読むために、即興で何かをしたいと思います。

USE <databaseName>;

SELECT o.[name]
    , m.[definition]
FROM sys.sql_modules m 
INNER JOIN sys.objects o 
    ON m.[object_id]=o.[object_id]
WHERE 1=1
    AND is_ms_shipped = 0 -- to exclude system stored proc
    AND [type_desc] = 'SQL_STORED_PROCEDURE'
    AND m.[definition] not like '%SET%NOCOUNT%ON%'; -- your search

さて、

  • ここでは、名前と定義の両方を使用できるため、各SPに対してsp_helptextを実行する必要がなく、これも高速になります。
  • ここでのすべての項目には、定義にSET NOCOUNT ONがありません。一致は、SpacesおよびTabsと一致するように%を使用して行われます(@からのコメントごと)アーロン)
  • ここで、Appendingスニペットが適切であるため、テキストを追加して更新するために必要な最後のステップですが、トリッキーですが。
  • ここでOPは、Beginの後にのみ最初に追加するように要求します。
1
MarmiK