何千ものストアドプロシージャを含むデータベースがあり、何百ものストアドプロシージャを変更する必要があります。
それをより速くするために、すべてのストアドプロシージャを実行し、最初にコードを追加する(必要な場合)スクリプトを作成する方法を考えました。
たとえば、存在しない場合に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
sys.procedures
からすべての手順を取得することから始めます
SELECT * FROM sys.Procedures
次に、それぞれにEXEC sp_helptext
を使用して、プロシージャのテキストをロードします。
追加するテキストを検索し、必要に応じて追加し、
次に、更新されたテキストを変数にロードし、動的に実行します。
上記の@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_helptext
を実行する必要がなく、これも高速になります。SET NOCOUNT ON
がありません。一致は、Spaces
およびTabs
と一致するように%
を使用して行われます(@からのコメントごと)アーロン)