メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
ストアドプロシージャは、サーバー上で実行される名前付きの SQL ブロックです。一度呼び出すと、その中にあるすべてのステートメントが実行されます。コードはアプリケーションではなくデータベースにあります。

ストアドプロシージャの作成

MySQL は DELIMITER を使ってステートメントの終端文字を変更し、プロシージャ本体の中の ; が CREATE PROCEDURE ステートメントを途中で終わらせないようにします。
CALL で呼び出します。
削除します。
定義を表示します。

パラメータ

プロシージャは 3 つのパラメータモードをサポートします。
OUT パラメータにはユーザー定義変数を使って呼び出します。

ローカル変数

ローカル変数は、BEGIN...END ブロックの先頭で、他のどのステートメントよりも前に DECLARE で宣言します。

制御フロー

MySQL のプロシージャは標準的な制御フロー構文をサポートします。

エラー処理

エラーを捕捉するには DECLARE ... HANDLER を使います。
EXIT HANDLER は、条件が発生するとプロシージャを停止します。CONTINUE HANDLER はプロシージャの実行を続行させます。RESIGNAL はエラーを呼び出し元に再送出します。 独自のエラーは SIGNAL で送出します。
45000 は「未処理のユーザー定義例外」を表す SQLSTATE です。

カーソル

カーソルは、プロシージャ内で結果セットを 1 行ずつ反復処理します。ロジックを集合演算として表現できない場合に使います。
NOT FOUND ハンドラーは、カーソルの行がなくなると v_done を設定します。プロシージャが終了する前に、必ずカーソルを閉じてください。

ストアドプロシージャとストアドファンクションの比較

ロジックを SQL の式に埋め込む必要がある場合はファンクションを使います。それ以外のすべて、つまり複数ステップの処理、条件付きロジック、副作用にはプロシージャを使います。

ストアドプロシージャを使うべき場合

ストアドプロシージャが適しているのは次の場合です。
  • どのアプリケーションやユーザーがクエリを実行するかに関係なく適用しなければならないビジネスルールを強制する
  • 複数ステップの操作(複雑なバッチジョブ、データ移行)の往復を減らす
  • 基礎となるテーブルを公開せずに、ユーザーに特定の操作へのアクセスを許可する(GRANT EXECUTE ON PROCEDURE)
害になるのは次の場合です。
  • ロジックが頻繁に変わる — デプロイに ALTER PROCEDURE または DROP と再作成が必要になる
  • デバッグが必要 — デバッガーはなく、SIGNAL ベースのログ出力のみ
  • 移植性が重要 — ストアドプロシージャの構文は MySQL 固有

よくある質問

ストアドプロシージャは結果セットを返せますか?

はい。プロシージャ内の INTO を使わない SELECT は、結果セットを呼び出し元に送ります。
1 つのプロシージャ内の複数の SELECT ステートメントは、複数の結果セットを送ります。ほとんどのクライアントはこれを処理できますが、一部の ORM は処理できません。

データベース内のすべてのストアドプロシージャを確認するには?

トラブルシューティング

VillageSQL: ストアドプロシージャでのカスタム拡張機能型

VillageSQL のカスタム拡張機能型(COMPLEX、UUID、TVECTOR など)は、ストアドプロシージャの パラメータ型および DECLARE 変数の型として使用できます。まず拡張機能をインストールし、 次にプロシージャ定義でその型を参照します。
いずれかのストアドプロシージャがその拡張機能のカスタム型を使用している間、UNINSTALL EXTENSION は失敗します。 拡張機能をアンインストールする前に、プロシージャを削除または変更してください。詳細は 拡張機能のアンインストールを参照してください。

関連項目