ストアドプリシーじゃの書き方を毎回思い出しているので、メモとして記載しておきます。
動作確認は SQL Server 2005 Development Edition で行っています。
1. ストアドプロシージャ定義テンプレート
1.1 パラメタなしプロシージャ
パラメタのないストアドプロシージャを作成します。最初にストアドプロシージャが定義している場合は作成前にDROP文で削除しています。
-- データベース名を指定する場合 USE [Component]; GO -- 基本的なストアドプロシージャテンプレート IF OBJECT_ID(N'[dbo].[usp_sampleprocedure]') IS NOT NULL DROP PROCEDURE [dbo].[usp_sampleprocedure]; GO CREATE PROCEDURE [dbo].[usp_sampleprocedure] AS BEGIN SET NOCOUNT ON; SELECT COUNT(*) FROM [dbo].[Article]; END GO
SQL Server Management Studio 上でストアドを実行する場合は次のように実行します。
EXEC dbo.usp_sampleprocedure
1.2パラメタつきプロシージャ
パラメタつきプロシージャを作成します。パラメタが指定されなかった場合のデフォルト値と、ストアド実行結果が値が設定されるOUTPUTを使用した例も同時に掲載します。ArticleCountパラメタがストアドを呼び出した結果値が設定されるパラメタであり、@CategoryIDのパラメタ定義で既定値を設定しています。
-- 基本的なストアドプロシージャテンプレート IF OBJECT_ID(N'[dbo].[usp_sampleprocedure]') IS NOT NULL DROP PROCEDURE [dbo].[usp_sampleprocedure]; GO CREATE PROCEDURE [dbo].[usp_sampleprocedure] @PublishDate datetime ,@CategoryID int = 0 ,@ArticleCount int OUTPUT AS BEGIN SET NOCOUNT ON; IF @CategoryID = 0 BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate END ELSE BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate AND CategoryID = @CategoryID END SELECT @ArticleCOunt = @@ROWCOUNT END
SSMS上で実行する場合は次のように呼び出します。
DECLARE @ArticleCount int EXEC dbo.usp_sampleprocedure '2009/01/02', 1, @ArticleCount OUTPUT PRINT @ArticleCount
1.3 ストアドを修正する
ストアドプロシージャを修正する場合は、ALTER文を使用します。
-- ストアドを修正する場合 ALTERを使用します。 ALTER PROCEDURE [dbo].[usp_sampleprocedure] @PublishDate datetime ,@CategoryID int = 0 ,@ArticleCount int OUTPUT AS BEGIN SET NOCOUNT ON; IF @CategoryID = 0 BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate END ELSE BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate AND CategoryID = @CategoryID END SELECT @ArticleCOunt = @@ROWCOUNT END
1.4 ストアドプロシージャを削除する
ストアドを修正するにはDROP文を使用します。
DROP PROCEDURE [dbo].[usp_sampleprocedure]
2. ストアド便利情報
2.1 SQL Server 起動時に自動的にプロシージャを実行する
sp_procoptionを使用します。Books Online を確認すれば分かりますが、指定できるオプションはstartupのみです。
-- SQL Server が起動するときに自動実行するストアドを定義する USE [master] GO sp_procoption @ProcName = '[dbo].[usp_startupprocedure]' , @OptionName = 'startup' , @OptionValue = 'true'
2.2 ストアドやVIEWの定義SQLを取得する
sys.sql_modules カタログビューを使用するとストアドやVIEW,関数などの定義情報などが取得できます。サンプルでは、sys.objectsカタログビューを使用してオブジェクトのタイプ(関数,VIEWなど)情報も表示しています。
SELECT o.name, o.type, o.type_desc, m.definition, m.* FROM sys.sql_modules m INNER JOIN sys.objects o ON m.object_id = o.object_id
2.3 ストアドを列挙する
sys.objects カタログビューを使用して関数や、ビューを列挙することができます。
-- ストアドを列挙する SELECT name FROM sys.objects WHERE type = 'P'
2.4 ストアドの定義内容を表示する
sp_helptextを使用するとユーザー定義のルール、既定値、暗号化されていない Transact-SQL ストアド プロシージャ、ユーザー定義の Transact-SQL 関数、トリガ、計算列、CHECK 制約、ビュー、またはシステム ストアド プロシージャなどのシステム オブジェクトの定義を表示することができます。
EXEC sp_helptext 'usp_articleUpdateComment'
ストアドの定義情報を見られないようにするには暗号化をします。暗号化するにはストアド定義時にWITH ENCRYPTION を指定します。
-- ストアドを暗号化する CREATE PROCEDURE usp_articleUpdate WITH ENCRYPTION AS UPDATE ... GO
2.5 ストアド実行権限を付与する
ストアドの実行権限を使用するにはGRANT EXEC を使用します。下のクエリでは、someuserユーザにストアドの実行権限を付与しています。someuserがテーブルのアクセス権がなくとも、ストアドを実行できるようになります。ただし、TRUNCATE TABLEをストアド内で使用している場合は、TRUNCATE TABLE権限がない場合、エラーが発生します。TRUNCATE TABLEの場合に必要な権限はBOOKS Online を参照してください。
GRANT EXEC ON usp_articleUpdateComment TO someuser
特定のユーザにストアドのEXECUTE権限を付与するSQLを作成するには次の用になります。
SELECT 'GRANT EXEC ON ' + name + 'TO someuser' FROM sys.objects WHERE type = 'P'
2.6 ストアドプロシージャの実行ユーザのセキュリティコンテキストを指定する
ストアドプロシージャ定義時にEXECUTE AS {CALLER | SELF | OWNER | 'user_name'} を指定すると、ストアドプロシージャ実行時のセキュリティコンテキストを指定できます。既定はCALLERなので、ストアドの呼び出しユーザのセキュリティコンテキスト上で実行されます。CALLER の場合、sp_execsqlなど、動的SQLを使用してSELECTしている場合、EXECUTE権限だけでなく、テーブルのSELECT権限なども必要になります。EXECUTE AS オプションを指定することで、ストアドの実行時セキュリティコンテキストをownerやとくていのユーザに指定できます。
CALLER | ストアドの呼び出しユーザの権限を使用します。 |
SELF | ストアドの作成ユーザか、最終変更者の権限を使用します。 |
OWNER | ストアドプロシージャのスキーマの所有者の権限を使用します。 |
'user_name' | 指定されたデータベースユーザの権限を使用します。 |
以下の例では、ONWERを指定しています。
CREATE PROCEDURE [dbo].[usp_sampleprocedure] @PublishDate datetime ,@CategoryID int = 0 ,@ArticleCount int OUTPUT WITH EXECUTE AS OWNER AS BEGIN SET NOCOUNT ON; IF @CategoryID = 0 BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate END ELSE BEGIN DELETE dbo.TestTable WHERE PublishDate < @PublishDate AND CategoryID = @CategoryID END SELECT @ArticleCOunt = @@ROWCOUNT END
2.7 ストアドプロシージャのキャッシュされた実行計画をクリアする
SQL Server 全体のキャッシュをクリアする場合は DBCC FREEPROCCACHE を使用します。キャッシュされているクエリの実行計画を表示する場合は、 sys.dm_exec_cached_plans 動的管理ビューに大してSELECTを発行します。
select * from sys.dm_exec_cached_plans
CREATE PROCEDURE文でWITH RECOMPILE を指定するとクエリの実行計画がキャッシュされないようになります。
3. おわり
説明は以上です。間違い等があればご指摘ください。
さんのコメント: さんのコメント: