CREATE PROCEDURE (Transact-SQL)

更新 : 2006 年 12 月 12 日

ストアド プロシージャを作成します。ストアド プロシージャは、Transact-SQL ステートメントをまとめて保存したものです。また Microsoft .NET Framework 共通言語ランタイム (CLR) メソッドへの参照として使用することもできます。このメソッドでは、ユーザー指定のパラメータを受け取り、結果を返すことができます。プロシージャは、永続的な使用、1 つのセッション内での一時使用 (ローカル一時プロシージャ)、または全セッションでの一時使用 (グローバル一時プロシージャ) を目的として作成できます。

ストアド プロシージャは、SQL Server インスタンスの起動時に自動的に実行するよう作成することもできます。

トピック リンク アイコンTransact-SQL 構文表記規則

構文

CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ; number ] 
    [ { @parameter [ type_schema_name. ] data_type } 
        [ VARYING ] [ = default ] [ OUT | OUTPUT ]
    ] [ ,...n ] 
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ] 
AS { <sql_statement> [;][ ...n ] | <method_specifier> }
[;]
<procedure_option> ::= 
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE_AS_Clause ]

<sql_statement> ::= 
{ [ BEGIN ] statements [ END ] }

<method_specifier> ::=
EXTERNAL NAME assembly_name.class_name.method_name

引数

  • schema_name
    プロシージャが所属するスキーマの名前を指定します。
  • procedure_name
    新しいストアド プロシージャの名前を指定します。プロシージャ名は、識別子の規則に従うと共に、スキーマ内で一意であることが必要です。

    プロシージャ名の先頭には sp_ を使用しないことを強くお勧めします。このプレフィックスは、SQL Server でシステム ストアド プロシージャの指定に使用されるものです。詳細については、「ストアド プロシージャの作成 (データベース エンジン)」を参照してください。

    ローカルまたはグローバルの一時プロシージャを作成するには、procedure_name の前に、ローカル一時プロシージャの場合はシャープ記号 (#) を 1 つ付加し (#procedure_name)、グローバル一時プロシージャの場合はシャープ記号を 2 つ付加します (##procedure_name)。CLR ストアド プロシージャには一時名は指定できません。

    ストアド プロシージャまたはグローバル一時ストアド プロシージャの名前は、## を含め最大で半角 128 文字です。ローカル一時ストアド プロシージャの名前は、# を含め最大で半角 116 文字です。

  • **;**number
    同じ名前のプロシージャのグループ化に使用される整数です (省略可能)。グループ化したプロシージャは、DROP PROCEDURE ステートメントの 1 回の実行でまとめて削除できます。たとえば、orders というアプリケーションでは、orderproc;1orderproc;2 のような名前のプロシージャを使用でき、DROP PROCEDURE orderproc ステートメントを使用すると、グループ全体が削除されます。名前に区切り記号付きの識別子が含まれる場合、数字を識別子に含めることはできません。procedure_name だけを適切な区切り記号で囲む必要があります。

    番号付きストアド プロシージャには次の制限があります。

    • データ型に xml または CLR ユーザー定義型は使用できない。
    • 番号付きストアド プロシージャにはプラン ガイドを作成できない。
    ms187926.note(ja-jp,SQL.90).gifメモ :
    この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。
  • **@**parameter
    プロシージャ内のパラメータを指定します。CREATE PROCEDURE ステートメント内では 1 つ以上のパラメータを宣言できます。宣言されている各パラメータの値は、パラメータに既定値が定義されているか、別のパラメータと同じ値を使用するよう設定されていない限り、プロシージャの呼び出し時にユーザーが指定する必要があります。ストアド プロシージャには最高 2,100 個のパラメータを指定できます。

    パラメータ名は、最初の文字をアット マーク (@) にして指定します。パラメータ名は識別子の規則に従っている必要があります。パラメータはプロシージャに対してローカルです。同じパラメータ名を他のプロシージャで使用できます。既定では、パラメータは定数式の代わりにのみ使用することができます。テーブル名、列名、またはその他のデータベース オブジェクト名の代わりにパラメータを使用することはできません。詳細については、「EXECUTE (Transact-SQL)」を参照してください。

    FOR REPLICATION を指定した場合、パラメータは宣言できません。

  • [ type_schema_name**.** ] data_type
    パラメータのデータ型とそれが属するスキーマを指定します。table 型を除くすべてのデータ型を、Transact-SQL ストアド プロシージャのパラメータとして使用できます。ただし、cursor 型は OUTPUT パラメータにのみ使用できます。cursor 型を指定する場合は、VARYING キーワードと OUTPUT キーワードも指定する必要があります。cursor 型では複数の出力パラメータを指定できます。

    CLR ストアド プロシージャの場合、charvarchartextntextimagecursor、および table 型はパラメータとして指定できません。CLR 型と SQL Server システム データ型の対応関係の詳細については、「SQL Server データ型と .NET Framework データ型の対応」を参照してください。SQL Server システム データ型とその構文に関する詳細については、「データ型 (Transact-SQL)」を参照してください。

    パラメータのデータ型が CLR ユーザー定義型の場合は、その型に対する EXECUTE 権限が必要です。

    type_schema_name を指定しない場合、SQL Server 2005 データベース エンジンは次の順序で type_name を参照します。

    • SQL Server システム データ型
    • 現在のデータベースにおける現在のユーザーに既定のスキーマ
    • 現在のデータベースの dbo スキーマ

    番号付きストアド プロシージャの場合、データ型は xml または CLR ユーザー定義型にできません。

  • VARYING
    出力パラメータとしてサポートされている結果セットを指定します。このパラメータはストアド プロシージャによって動的に作成され、その内容は変化します。cursor パラメータにのみ適用されます。
  • default
    パラメータの既定値です。default 値が定義されている場合は、パラメータに値を指定せずにプロシージャを実行できます。既定値は定数にする必要がありますが、NULL にすることもできます。プロシージャで LIKE キーワードと共にパラメータが使用される場合、ワイルドカード文字 %、_、[]、および [^] を含めることができます。

    ms187926.note(ja-jp,SQL.90).gifメモ :
    既定値は、CLR プロシージャの場合のみ、sys.parameters.default 列に記録されます。この列は、Transact-SQL プロシージャ パラメータでは NULL になります。
  • OUTPUT
    パラメータが出力パラメータであることを示します。このオプションの値は、EXECUTE ステートメントの呼び出しに対して返すことができます。プロシージャの呼び出し元に値を返すには、OUTPUT パラメータを使用します。textntext、および image パラメータは、プロシージャが CLR プロシージャでない限り、OUTPUT パラメータとして使用できません。OUTPUT キーワードを使用する出力パラメータは、プロシージャが CLR プロシージャでない限り、カーソルのプレースホルダにできます。
  • RECOMPILE
    データベース エンジンでこのプロシージャ用のプランをキャッシュせず、プロシージャを実行時にコンパイルすることを示します。このオプションは、FOR REPLICATION を指定した場合は使用できません。CLR ストアド プロシージャには RECOMPILE は指定できません。

    データベース エンジンでストアド プロシージャ内にある個々のクエリに対するプランを破棄するには、RECOMPILE クエリ ヒントを使用します。詳細については、「クエリ ヒント (Transact-SQL)」を参照してください。RECOMPILE クエリ ヒントを使用するのは、非定型の値や一時的な値が、ストアド プロシージャに属するクエリのサブセットでのみ使用されている場合です。

  • ENCRYPTION
    SQL Server で、CREATE PROCEDURE ステートメントの元のテキストを、暗号化した形式に変換することを示します。暗号化した形式の出力は、SQL Server 2005 内のどのカタログ ビューでも直接見ることはできません。システム テーブルまたはデータベース ファイルへのアクセス権を持たないユーザーは、暗号化した形式のテキストを取得できません。DAC ポート経由でシステム テーブルにアクセスする権限、または直接データベース ファイルにアクセスする権限を持っているユーザーは、このテキストを使用できます。また、サーバー プロセスにデバッガをアタッチできるユーザーは、実行時、暗号化を解除したプロシージャをメモリから取得できます。システム メタデータへのアクセスの詳細については、「メタデータ表示の構成」を参照してください。

    このオプションは、CLR ストアド プロシージャでは無効です。

    このオプションを使って作成したプロシージャを、SQL Server レプリケーションの一部として発行することはできません。

  • EXECUTE AS
    ストアド プロシージャを実行するセキュリティ コンテキストを指定します。

    詳細については、「EXECUTE AS 句 (Transact-SQL)」を参照してください。

  • FOR REPLICATION
    レプリケーション用に作成したストアド プロシージャは、サブスクライバでは実行できないことを示します。FOR REPLICATION オプションを指定して作成したストアド プロシージャは、ストアド プロシージャ フィルタとして使用され、レプリケーション時にのみ実行されます。FOR REPLICATION を指定した場合、パラメータは宣言できません。CLR ストアド プロシージャには FOR RECOMPILE は指定できません。RECOMPILE オプションは、FOR REPLICATION を使って作成されたプロシージャでは無視されます。

    FOR REPLICATION プロシージャでは、sys.objects および sys.procedures でオブジェクトの種類 RF が指定されます。

  • <sql_statement>
    プロシージャに含める 1 つ以上の Transact-SQL ステートメントを指定します。適用されるいくつかの制限については、「解説」を参照してください。
  • EXTERNAL NAME assembly_name**.class_name.method_name
    CLR ストアド プロシージャで参照する .NET Framework アセンブリのメソッドを指定します。class_name は有効な SQL Server 識別子で、アセンブリ内にクラスとして存在する必要があります。クラス名に名前空間とその区切り文字のピリオド (
    .) が含まれる場合は、クラス名をかっこ ([]) または引用符 (""**) で区切る必要があります。指定するメソッドは、クラスの静的メソッドであることが必要です。

    ms187926.note(ja-jp,SQL.90).gifメモ :
    既定では、SQL Server で CLR コードを実行することはできません。CLR モジュールを参照するデータベース オブジェクトを作成、変更、削除することはできませんが、これらの参照を SQL Server で実行するには、clr enabled option を有効にする必要があります。このオプションを有効にするには、sp_configure を使用します。

解説

ストアド プロシージャの最大サイズはあらかじめ定義されていません。

ユーザー定義ストアド プロシージャは、現在のデータベースでのみ作成できます。一時プロシージャは例外で、これは常に tempdb で作成されます。スキーマ名を指定しない場合は、プロシージャを作成しているユーザーの既定のスキーマが使用されます。スキーマの詳細については、「ユーザーとスキーマの分離」を参照してください。

1 つのバッチ内に CREATE PROCEDURE ステートメントと他の Transact-SQL ステートメントを混在させることはできません。

既定では、パラメータに NULL 値は許容されます。NULL パラメータ値が渡され、そのパラメータが、参照列に対して NULL 値を許容しない CREATE TABLE ステートメントまたは ALTER TABLE ステートメントで使用されると、データベース エンジンではエラーが生成されます。NULL 値が許容されない列に NULL パラメータ値が渡されないようにするには、プロシージャにプログラミング ロジックを追加するか、CREATE TABLE または ALTER TABLE で DEFAULT キーワードを使用して、列の既定値を指定します。

一時テーブル内の各列には、NULL または NOT NULL を明示的に指定することをお勧めします。CREATE TABLE および ALTER TABLE ステートメントで NULL または NOT NULL 属性が指定されていない場合、ANSI_DFLT_ON および ANSI_DFLT_OFF オプションを使用すると、データベース エンジンが NULL や NOT NULL 属性を列に割り当てる方法を制御できます。ある接続でこれらのオプションを使用してストアド プロシージャを実行する場合、オプションの設定がプロシージャを作成した接続時とは異なっていると、新しい接続で作成されるテーブルの列に対して、異なる NULL 許容属性や異なる動作を指定することができます。各列に NULL または NOT NULL を明示的に宣言すると、ストアド プロシージャを実行するすべての接続に対して同じ NULL 許容属性を使用することにより、複数の一時テーブルが作成されます。

SET オプションの使用

Transact-SQL ストアド プロシージャを作成または変更すると、データベース エンジンでは SET QUOTED_IDENTIFIER と SET ANSI_NULLS の両方の設定が保存されます。これらの元の設定は、ストアド プロシージャの実行時に使用されます。したがって、ストアド プロシージャの実行中は、SET QUOTED_IDENTIFIER と SET ANSI_NULLS のクライアント セッションの設定は無視されます。SET ARITHABORT、SET ANSI_WARNINGS、SET ANSI_PADDINGS など他の SET オプションは、ストアド プロシージャの作成時または変更時に保存されません。ストアド プロシージャのロジックが特定の設定に依存する場合は、プロシージャの先頭に SET ステートメントを挿入し、適切な設定を確保します。ストアド プロシージャから SET ステートメントを実行すると、その設定は、ストアド プロシージャが実行を終了するまでの間だけ有効です。ストアド プロシージャが終了すると、その設定は、ストアド プロシージャが呼び出されたときの値に復元されます。この機能を使用すると、個々のクライアントでストアド プロシージャのロジックに影響を与えずに必要なオプションを設定できます。

ms187926.note(ja-jp,SQL.90).gifメモ :
ストアド プロシージャでパラメータを引き渡す場合や、バッチ ステートメントで変数を宣言または設定する場合、またはユーザー定義関数においては、ANSI_WARNINGS は無視されます。たとえば、変数を char(3) として定義し、3 文字より長い値を指定すると、データは定義されたサイズに切り捨てられ、INSERT または UPDATE ステートメントは成功します。

CLR ストアド プロシージャでのパラメータの使用

CLR ストアド プロシージャのパラメータは、スカラ SQL Server システム データ型の 1 つをとることができます。

データベース エンジンが .NET Framework でオーバーロードされるときに正しいメソッドを参照するようにするには、<method_specifier> で指定されるメソッドが次の条件に該当する必要があります。

  • 静的メソッドとして宣言される。
  • プロシージャのパラメータ数と同じ数のパラメータを受け取る。
  • 自身のクラスのコンストラクタまたはデストラクタではない。
  • SQL Server プロシージャの対応するパラメータのデータ型と互換性のあるパラメータ型を使用する。SQL Server データ型に一致する .NET Framework データ型については、「SQL Server データ型と .NET Framework データ型の対応」を参照してください。
  • void または SQLInt32SQLInt16System.Int32、または System.Int16 型の値のいずれかを返す。
  • 特定のパラメータ宣言に OUTPUT を指定する場合、パラメータを値ではなく参照で返す。

ストアド プロシージャに関する情報の取得

Transact-SQL ストアド プロシージャの定義を表示するには、そのプロシージャが存在するデータベースの sys.sql_modules カタログ ビューを使用します。

次に例を示します。

USE AdventureWorks;
GO
SELECT definition 
FROM sys.sql_modules 
JOIN sys.objects ON sys.sql_modules.object_id = sys.objects.object_id AND TYPE = 'P';
ms187926.note(ja-jp,SQL.90).gifメモ :
ENCRYPTION オプションで作成されるストアド プロシージャのテキストは、sys.sql_modules カタログ ビューを使って表示できません。

プロシージャが参照するオブジェクトについてのレポートを取得するには、sys.sql_dependencies カタログ ビューにクエリを実行するか、sp_depends を使用します。sp_depends では、CLR ストアド プロシージャが参照するオブジェクトについての情報は返されません。CLR ストアド プロシージャに関する情報を表示するには、プロシージャが存在するデータベースの sys.assembly_modules カタログ ビューを使用します。

ストアド プロシージャで定義されているパラメータに関する情報を表示するには、プロシージャが存在するデータベースの sys.parameters カタログ ビューを使用します。

名前の遅延解決

まだ存在していないテーブルを参照するストアド プロシージャを作成できます。作成時には、構文チェックのみが行われます。ストアド プロシージャは、最初の実行時までコンパイルされません。ストアド プロシージャ内で参照されているすべてのオブジェクトが解決されるのは、コンパイル時のみです。したがって、存在しないテーブルを参照するストアド プロシージャは、構文が正しければ正常に作成できます。ただし、実行時に参照されるテーブルが存在しない場合、ストアド プロシージャは失敗します。詳細については、「名前の遅延解決とコンパイル」を参照してください。

ストアド プロシージャの実行

ユーザー定義ストアド プロシージャを実行するとき、バッチ内、またはユーザー定義ストアド プロシージャや関数などのモジュール内で実行する場合は、ストアド プロシージャ名にスキーマ名を追加することを強くお勧めします。

パラメータ値を指定できるようにストアド プロシージャが作成されている場合は、パラメータ値を指定できます。指定する値は定数または変数であることが必要です。関数名をパラメータ値として指定することはできません。変数の場合、ユーザー定義変数または @@SPID などのシステム変数を指定できます。

詳細については、「ストアド プロシージャの実行 (データベース エンジン)」を参照してください。

プロシージャは最初の実行時にコンパイルされ、データを取得するための最適なアクセス プランが決定されます。ストアド プロシージャがデータベース エンジンのプラン キャッシュに残っている場合、次にそのストアド プロシージャを実行するときには生成済みのプランを再使用できます。詳細については、「実行プランのキャッシュと再利用」を参照してください。

cursor 型を使用するパラメータ

Transact-SQL ストアド プロシージャでは、OUTPUT パラメータにのみ cursor 型を使用できます。パラメータに cursor 型を指定する場合は、VARYING パラメータと OUTPUT パラメータの両方が必要です。パラメータに VARYING キーワードを指定する場合は、データ型を cursor にして、OUTPUT キーワードを指定する必要があります。詳細については、「OUTPUT パラメータでの cursor データ型の使用」を参照してください。

一時ストアド プロシージャ

データベース エンジンでは、ローカルとグローバルの 2 種類の一時プロシージャがサポートされます。ローカル一時プロシージャは、そのプロシージャが作成された接続でのみ使用できます。グローバル一時プロシージャは、すべての接続で使用することができます。ローカル一時プロシージャは、現在のセッションの終了時に自動的に削除されます。グローバル一時プロシージャは、プロシージャを使用する最後のセッションが終了するときに削除されます。詳細については、「ストアド プロシージャの作成 (データベース エンジン)」を参照してください。

ストアド プロシージャの自動実行

SQL Server の起動時に、1 つ以上のストアド プロシージャを自動的に実行できます。このストアド プロシージャは、システム管理者によって master データベースに作成される必要があり、sysadmin 固定サーバー ロールの下でバックグラウンド プロセスとして実行される必要があります。プロシージャに入力または出力パラメータを指定することはできません。詳細については、「ストアド プロシージャの自動実行」を参照してください。

ストアド プロシージャの入れ子

ストアド プロシージャは入れ子にできます。つまり、1 つのストアド プロシージャから、別のストアド プロシージャを呼び出すことができます。呼び出されたプロシージャが実行を開始すると入れ子レベルが 1 つ上がり、呼び出されたプロシージャが実行を終了するとレベルが 1 つ下がります。ストアド プロシージャは 32 レベルまで入れ子にできます。詳細については、「ストアド プロシージャの入れ子」を参照してください。

コンパイル後のストアド プロシージャのサイズを予測するには、次のパフォーマンス モニタ カウンタを使用します。

パフォーマンス モニタ オブジェクト名 パフォーマンス モニタ カウンタ名

SQLServer: Plan Cache オブジェクト

Cache Hit Ratio

 

Cache Pages

 

キャッシュ オブジェクト数*

* アドホック SQL、準備された SQL、プロシージャ、トリガなど、キャッシュ オブジェクトの種類別にオブジェクトの数を調べることができます。

詳細については、「SQL Server の Plan Cache オブジェクト」を参照してください。

<sql_statement> の制限

SET ステートメントは、SET SHOWPLAN_TEXT および SET SHOWPLAN_ALL を除き、ストアド プロシージャ内部で指定できます。バッチで同時に他のステートメントを実行することはできません。選択した SET オプションは、ストアド プロシージャの実行中は有効で、実行後に元の設定に戻されます。

ストアド プロシージャの所有者以外のユーザーがストアド プロシージャを使用する場合、ストアド プロシージャの内部では、CREATE、ALTER、または DROP ステートメントなどのすべてのデータ定義言語 (DDL) ステートメント、DBCC ステートメント、EXECUTE および動的 SQL ステートメントで使用するオブジェクト名には、オブジェクト スキーマの名前を追加する必要があります。詳細については、「ストアド プロシージャの設計 (データベース エンジン)」を参照してください。

権限

データベースの CREATE PROCEDURE 権限と、プロシージャを作成するスキーマに対する ALTER 権限が必要です。

CLR ストアド プロシージャの場合は、<method_specifier> で参照されるアセンブリの所有権、またはそのアセンブリの REFERENCES 権限が必要です。

A. 単純なプロシージャを使用する

次のストアド プロシージャは、全従業員 (氏名を提供) と、その役職および部署名を、ビューから返します。このストアド プロシージャではパラメータをまったく使用しません。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.uspGetAllEmployees', 'P' ) IS NOT NULL 
    DROP PROCEDURE HumanResources.uspGetAllEmployees;
GO
CREATE PROCEDURE HumanResources.uspGetAllEmployees
AS
    SET NOCOUNT ON;
    SELECT LastName, FirstName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment;
GO

ストアド プロシージャ uspGetEmployees は次のように実行されます。

EXECUTE HumanResources.uspGetAllEmployees;
GO
-- Or
EXEC HumanResources.uspGetAllEmployees;
GO
-- Or, if this procedure is the first statement within a batch:
HumanResources.uspGetAllEmployees;

B. 単純なプロシージャをパラメータと共に使用する

次のストアド プロシージャは、特定の 1 人の従業員 (氏名を提供) と、その役職および部署名を、ビューから返します。このストアド プロシージャは、渡されたパラメータと完全に一致するものを受け入れます。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.uspGetEmployees', 'P' ) IS NOT NULL 
    DROP PROCEDURE HumanResources.uspGetEmployees;
GO
CREATE PROCEDURE HumanResources.uspGetEmployees 
    @LastName nvarchar(50), 
    @FirstName nvarchar(50) 
AS 
    
    SET NOCOUNT ON;
    SELECT FirstName, LastName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment
    WHERE FirstName = @FirstName AND LastName = @LastName;
GO

ストアド プロシージャ uspGetEmployees は次のように実行されます。

EXECUTE HumanResources.uspGetEmployees N'Ackerman', N'Pilar';
-- Or
EXEC HumanResources.uspGetEmployees @LastName = N'Ackerman', @FirstName = N'Pilar';
GO
-- Or
EXECUTE HumanResources.uspGetEmployees @FirstName = N'Pilar', @LastName = N'Ackerman';
GO
-- Or, if this procedure is the first statement within a batch:
HumanResources.uspGetEmployees N'Ackerman', N'Pilar';

C. 単純なプロシージャをワイルドカード パラメータと共に使用する

次のストアド プロシージャは、特定の複数の従業員 (氏名を提供) と、その役職および部署名を、ビューから返します。このストアド プロシージャでは、渡されるパラメータのパターン マッチが行われます。パラメータが指定されない場合は、あらかじめ設定された既定値が使用されます (姓の先頭文字が D)。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.uspGetEmployees2', 'P' ) IS NOT NULL 
    DROP PROCEDURE HumanResources.uspGetEmployees2;
GO
CREATE PROCEDURE HumanResources.uspGetEmployees2 
    @LastName nvarchar(50) = N'D%', 
    @FirstName nvarchar(50) = N'%'
AS 
    SET NOCOUNT ON;
    SELECT FirstName, LastName, JobTitle, Department
    FROM HumanResources.vEmployeeDepartment
    WHERE FirstName LIKE @FirstName AND LastName LIKE @LastName;
GO

uspGetEmployees2 ストアド プロシージャは、多くの組み合わせで実行できます。ここでは、いくつかの組み合わせのみを示します。

EXECUTE HumanResources.uspGetEmployees2;
-- Or
EXECUTE HumanResources.uspGetEmployees2 N'Wi%';
-- Or
EXECUTE HumanResources.uspGetEmployees2 @FirstName = N'%';
-- Or
EXECUTE HumanResources.uspGetEmployees2 N'[CK]ars[OE]n';
-- Or
EXECUTE HumanResources.uspGetEmployees2 N'Hesse', N'Stefen';
-- Or
EXECUTE HumanResources.uspGetEmployees2 N'H%', N'S%';

D. OUTPUT パラメータを使用する

次の例では、uspGetList ストアド プロシージャを作成します。このプロシージャは、指定の価格以下の製品の一覧を返します。この例では、複数の SELECT ステートメントと複数の OUTPUT パラメータを使用します。OUTPUT パラメータを使用すると、プロシージャの実行中に、外部プロシージャ、バッチ、または複数の Transact-SQL ステートメントから、値セットにアクセスできます。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'Production.uspGetList', 'P' ) IS NOT NULL 
    DROP PROCEDURE Production.uspGetList;
GO
CREATE PROCEDURE Production.uspGetList @Product varchar(40) 
    , @MaxPrice money 
    , @ComparePrice money OUTPUT
    , @ListPrice money OUT
AS
    SET NOCOUNT ON;
    SELECT p.[Name] AS Product, p.ListPrice AS 'List Price'
    FROM Production.Product AS p
    JOIN Production.ProductSubcategory AS s 
      ON p.ProductSubcategoryID = s.ProductSubcategoryID
    WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice;
-- Populate the output variable @ListPprice.
SET @ListPrice = (SELECT MAX(p.ListPrice)
        FROM Production.Product AS p
        JOIN  Production.ProductSubcategory AS s 
          ON p.ProductSubcategoryID = s.ProductSubcategoryID
        WHERE s.[Name] LIKE @Product AND p.ListPrice < @MaxPrice);
-- Populate the output variable @compareprice.
SET @ComparePrice = @MaxPrice;
GO

uspGetList を実行し、$700 より安い Adventure Works 製品 (バイク) の一覧を返します。ここではフロー制御と共に OUTPUT パラメータの @Cost および @ComparePrices を使用して、Messages ウィンドウにメッセージを返します。

ms187926.note(ja-jp,SQL.90).gifメモ :
OUTPUT 変数は、プロシージャの作成時と変数の使用時に定義する必要があります。パラメータ名と変数名は一致する必要はありませんが、データ型とパラメータの位置は一致する必要があります。ただし、@ListPrice= variable が使用されている場合を除きます。
DECLARE @ComparePrice money, @Cost money 
EXECUTE Production.uspGetList '%Bikes%', 700, 
    @ComparePrice OUT, 
    @Cost OUTPUT
IF @Cost <= @ComparePrice 
BEGIN
    PRINT 'These products can be purchased for less than 
    $'+RTRIM(CAST(@ComparePrice AS varchar(20)))+'.'
END
ELSE
    PRINT 'The prices for all products in this category exceed 
    $'+ RTRIM(CAST(@ComparePrice AS varchar(20)))+'.'

次に結果セットの一部を示します。

Product                                            List Price
-------------------------------------------------- ------------------
Road-750 Black, 58                                 539.99
Mountain-500 Silver, 40                            564.99
Mountain-500 Silver, 42                            564.99
...
Road-750 Black, 48                                 539.99
Road-750 Black, 52                                 539.99

(14 row(s) affected)

These items can be purchased for less than $700.00.

E. WITH RECOMPILE オプションを使用する

WITH RECOMPILE 句は、プロシージャに指定するパラメータが定型的でない場合や、新しい実行プランをメモリにキャッシュまたは保存したくない場合に役立ちます。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'dbo.uspProductByVendor', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.uspProductByVendor;
GO
CREATE PROCEDURE dbo.uspProductByVendor @Name varchar(30) = '%'
WITH RECOMPILE
AS
    SET NOCOUNT ON;
    SELECT v.Name AS 'Vendor name', p.Name AS 'Product name'
    FROM Purchasing.Vendor AS v 
    JOIN Purchasing.ProductVendor AS pv 
      ON v.VendorID = pv.VendorID 
    JOIN Production.Product AS p 
      ON pv.ProductID = p.ProductID
    WHERE v.Name LIKE @Name;
GO

F. WITH ENCRYPTION オプションを使用する

次の例では、HumanResources.uspEncryptThis ストアド プロシージャを作成します。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'HumanResources.uspEncryptThis', 'P' ) IS NOT NULL 
    DROP PROCEDURE HumanResources.uspEncryptThis;
GO
CREATE PROCEDURE HumanResources.uspEncryptThis
WITH ENCRYPTION
AS
    SET NOCOUNT ON;
    SELECT EmployeeID, Title, NationalIDNumber, VacationHours, SickLeaveHours 
    FROM HumanResources.Employee;
GO

次の例に示すように、WITH ENCRYPTION オプションを使用すると、ストアド プロシージャの定義が返されません。

sp_helptext を実行します。

EXEC sp_helptext 'HumanResources.uspEncryptThis';

以下に結果セットを示します。

The text for object 'HumanResources.uspEncryptThis' is encrypted.

sys.sql_modules カタログ ビューに直接クエリを実行します。

USE AdventureWorks;
GO
SELECT definition FROM sys.sql_modules
WHERE object_id = OBJECT_ID('HumanResources.uspEncryptThis');

以下に結果セットを示します。

definition
----------------------
NULL

(1 row(s) affected)

G. 名前の遅延解決を使用する

次の例では、uspProc1 プロシージャを作成します。ここでは名前の遅延解決を使用します。ストアド プロシージャは、参照されるテーブルがコンパイル時に存在しなくても作成されます。ただし、プロシージャの実行時にはテーブルが存在する必要があります。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'dbo.uspProc1', 'P' ) IS NOT NULL 
    DROP PROCEDURE dbo.uspProc1;
GO
CREATE PROCEDURE dbo.uspProc1
AS
    SET NOCOUNT ON;
    SELECT column1, column2 FROM table_does_not_exist
GO

ストアド プロシージャが作成されたことを確認するには、次のクエリを実行します。

USE AdventureWorks;
GO
SELECT definition
FROM sys.sql_modules
WHERE object_id = OBJECT_ID('dbo.uspproc1');

以下に結果セットを示します。

definition
-----------------------------------------------------------------------
CREATE PROCEDURE uspproc1
AS
    SELECT column1, column2 FROM table_does_not_exist

(1 row(s) affected)

H. EXECUTE AS 句を使用する

次の例では、EXECUTE AS 句を使用して、ストアド プロシージャを実行できるセキュリティ コンテキストを指定します。この例では、オプションの CALLER により、プロシージャを呼び出したユーザーのコンテキストでプロシージャを実行できることを指定します。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'Purchasing.uspVendorAllInfo', 'P' ) IS NOT NULL 
    DROP PROCEDURE Purchasing.uspVendorAllInfo;
GO
CREATE PROCEDURE Purchasing.uspVendorAllInfo
WITH EXECUTE AS CALLER
AS
    SET NOCOUNT ON;
    SELECT v.Name AS Vendor, p.Name AS 'Product name', 
      v.CreditRating AS 'Credit Rating', 
      v.ActiveFlag AS Availability
    FROM Purchasing.Vendor v 
    INNER JOIN Purchasing.ProductVendor pv
      ON v.VendorID = pv.VendorID 
    INNER JOIN Production.Product p
      ON pv.ProductID = p.ProductID 
    ORDER BY v.Name ASC;
GO

I. CLR ストアド プロシージャを作成する

次の例では、GetPhotoFromDB ストアド プロシージャを作成します。このストアド プロシージャでは、HandlingLOBUsingCLR アセンブリ内の LargeObjectBinary クラスの GetPhotoFromDB メソッドを参照します。ストアド プロシージャを作成する前に、HandlingLOBUsingCLR アセンブリはローカル データベースに登録されます。

CREATE ASSEMBLY HandlingLOBUsingCLR
FROM '\\MachineName\HandlingLOBUsingCLR\bin\Debug\HandlingLOBUsingCLR.dll'';
GO
CREATE PROCEDURE dbo.GetPhotoFromDB
(
    @ProductPhotoID int,
    @CurrentDirectory nvarchar(1024),
    @FileName nvarchar(1024)
)
AS EXTERNAL NAME HandlingLOBUsingCLR.LargeObjectBinary.GetPhotoFromDB;
GO

J. OUTPUT カーソル パラメータを使用する

OUTPUT カーソル パラメータは、ストアド プロシージャに対してローカルになっているカーソルを、呼び出し側のバッチ、ストアド プロシージャ、またはトリガに戻す場合に使用します。

まず、Currency テーブルに対してカーソルを宣言し、そのカーソルをオープンするプロシージャを作成します。

USE AdventureWorks;
GO
IF OBJECT_ID ( 'dbo.uspCurrencyCursor', 'P' ) IS NOT NULL
    DROP PROCEDURE dbo.uspCurrencyCursor;
GO
CREATE PROCEDURE dbo.uspCurrencyCursor 
    @CurrencyCursor CURSOR VARYING OUTPUT
AS
    SET NOCOUNT ON;
    SET @CurrencyCursor = CURSOR
    FORWARD_ONLY STATIC FOR
      SELECT CurrencyCode, Name
      FROM Sales.Currency;
    OPEN @CurrencyCursor;
GO

次に、ローカル カーソル変数を宣言し、ローカル変数にカーソルを割り当てるプロシージャを実行した後、カーソルから行を取り出すバッチを実行します。

USE AdventureWorks;
GO
DECLARE @MyCursor CURSOR;
EXEC dbo.uspCurrencyCursor @CurrencyCursor = @MyCursor OUTPUT;
WHILE (@@FETCH_STATUS = 0)
BEGIN;
     FETCH NEXT FROM @MyCursor;
END;
CLOSE @MyCursor;
DEALLOCATE @MyCursor;
GO

参照

関連項目

ALTER PROCEDURE (Transact-SQL)
流れ制御言語 (Transact-SQL)
データ型 (Transact-SQL)
DECLARE @local\_variable (Transact-SQL)
DROP PROCEDURE (Transact-SQL)
EXECUTE (Transact-SQL)
EXECUTE AS (Transact-SQL)
EVENTDATA (Transact-SQL)
関数 (Transact-SQL)
sp_depends (Transact-SQL)
sp_procoption (Transact-SQL)
sp_recompile (Transact-SQL)
sys.sql_modules (Transact-SQL)
sys.parameters (Transact-SQL)
sys.procedures (Transact-SQL)
sys.sql_dependencies (Transact-SQL)
sys.assembly_modules (Transact-SQL)
sys.numbered_procedures (Transact-SQL)
sys.numbered_procedure_parameters (Transact-SQL)
OBJECT_DEFINITION (Transact-SQL)

その他の技術情報

バッチ
カーソル (データベース エンジン)
ストアド プロシージャ (データベース エンジン)
変数とパラメータの使用 (データベース エンジン)
ストアド プロシージャを作成する方法 (SQL Server Management Studio)

ヘルプおよび情報

SQL Server 2005 の参考資料の入手

変更履歴

リリース 履歴

2006 年 12 月 12 日

変更内容 :
  • 「解説」に、ストアド プロシージャの最大サイズがあらかじめ定義されていないことを明記しました。