ストアドプロシージャ(英: Stored Procedure)は、リレーショナルデータベース管理システム(RDBMS)にアクセスするアプリケーションで利用できるサブルーチンである。このようなプロシージャは、データベースのデータ辞書に格納されている。

ストアドプロシージャの用途としては、データの検証(データベースへの統合)やアクセス制御の仕組みなどがある。さらに、ストアドプロシージャは、もともとアプリケーションに実装されていたロジックを統合し、一元化することができる。時間とメモリを節約するために、複数のSQL文の実行を必要とする大規模または複雑な処理をストアドプロシージャに保存し、すべてのアプリケーションはそのプロシージャを呼び出すことができる。ストアドプロシージャの中から別のストアドプロシージャを実行することで、ネストされたストアドプロシージャを使用することができる。

ストアドプロシージャは結果セット、つまり`SELECT`文の結果を返すことがある。このような結果セットは、カーソル、他のストアドプロシージャ、結果セットロケータの関連付け、またはアプリケーションによって処理することができる。ストアドプロシージャは、データを処理するための宣言された変数や、テーブルの複数の行をループするためのカーソルを含むこともできる。ストアドプロシージャのフロー制御文には、通常、`IF`、`WHILE`、`LOOP`、`REPEAT`、`CASE`文などがある。ストアドプロシージャは、変数の宣言方法と宣言場所によって、変数を受け取って結果を返したり、変数を変更して結果を返したりすることができる。

## 実装

ストアドプロシージャは、ユーザー定義関数(UDF)に似ている。大きな違いは、UDFはSQL文の中で他の式と同様に使用できるのに対し、ストアドプロシージャは`CALL`文を使って呼び出さなければならないことである。

または

ストアドプロシージャの正確で正しい実装は、データベースシステムによって異なる。ほとんどの主要なデータベースベンダーは、何らかの形でストアドプロシージャをサポートしている。ストアドプロシージャは、データベースシステムに応じて、SQL、Java、C、C++など、さまざまなプログラミング言語で実装することができる。SQL以外の言語で書かれたストアドプロシージャは、それ自体がSQL文を実行することも、しないこともある。

ストアドプロシージャの採用が進んだことで、SQL:1999とSQL:2003の標準SQL/PSMという部分で、SQL言語に手続き的な要素が導入されることになり、SQLは命令型プログラミング言語となった。ほとんどのデータベースシステムは,SQL/PSMを超える独自の拡張やベンダ固有の拡張を提供している.Javaストアドプロシージャの標準仕様は、SQL/JRTと同様に存在する。

| データベースシステム | 実装言語 |
| --- | --- |
| CUBRID | Java |
| IBM DB2 | SQL PL( SQL/PSM標準に近い)またはJava |
| Firebird | PSQL(FyracleはOracleのPL / SQLの一部もサポート) |
| Informix | Java |
| Interbase | ストアドプロシージャとトリガー言語 |
| Microsoft SQL Server | Transact-SQLおよびさまざまな.NET Framework言語 |
| MySQL 、 MariaDB | SQL/PSM標準に厳密に準拠した独自のストアドプロシージャ |
| NuoDB | SQLまたはJava |
| OpenLink Virtuoso | Virtuoso SQLプロシージャ(VSP); Java、C、およびその他のプログラミング言語を介して拡張可能 |
| Oracle | PL / SQLまたはJava |
| PostgreSQL | PL/pgSQLは、PL / PerlやPL / PHPなどの独自の関数言語を使用することも可能 |
| SAP HANA | SQLScriptまたはR |
| SAP ASE | Transact-SQL |
| SAP SQL Anywhere | Transact-SQL 、Watcom SQL |
| SQLite | サポートされていない |

## 静的SQLとの比較

ストアドプロシージャ文は直接データベースに格納されるため、ソフトウェアアプリケーションがインライン(動的)SQLクエリをデータベースに送信する状況で通常必要となるコンパイルのオーバーヘッドのすべてまたは一部を削除することができる。(ただし、ほとんどのデータベースシステムは、動的SQL文の反復的なコンパイルを避けるために、ステートメントキャッシュや他の方法を実装している)。また、プリコンパイルされたSQLをある程度回避できる一方で、SQL文のすべての引数がコンパイル時に提供されないため、最適な実行プランを作成するための複雑さが増す。特定のデータベースの実装や構成によっては、ストアドプロシージャと一般的なクエリやユーザー定義関数を比較した場合、性能に差が出ることがある。

ストアドプロシージャの大きな利点は、データベースエンジン内で直接実行できることである。本番システムでは、プロシージャは専用のデータベースサーバーで実行され、アクセスされるデータに直接アクセスできるのが一般的である。この利点は、ネットワーク通信コストを完全に回避できることである。これは、一連の複雑なSQL文の場合に、より重要になる。

ストアドプロシージャは、プログラマがビジネスロジックをAPIとしてデータベースに埋め込むことができるため、データ管理を簡素化し、クライアントプログラムの別の場所でロジックをエンコードする必要性を低減することができる。その結果、欠陥のあるクライアントプログラムによるデータ破損の可能性を低くすることができる。データベースシステムは、ストアドプロシージャの助けを借りて、データの整合性と一貫性を確保することができる。

多くのシステムでは、ストアドプロシージャに、そのプロシージャを実行するユーザーが直接持っていないデータベースへのアクセス権を与えることができる。

ストアドプロシージャは、インジェクション攻撃から保護するために使用することができる。ストアドプロシージャのパラメータは、攻撃者がSQLコマンドを挿入しても、データとして扱われる。また、DBMSによっては、パラメータの型をチェックするものもある。しかし、ストアドプロシージャが入力されたデータを使って動的SQLを生成する場合、適切な予防措置が取られない限り、SQLインジェクションの危険性があることに変わりはない。

## デメリット

- ストアドプロシージャ言語は、ベンダーに依存することが多い。データベースベンダーを変更する場合、通常、既存のストアドプロシージャを書き換える必要がある。
- ストアドプロシージャの変更は、他のコードに比べてバージョン管理システム内で追跡することが困難である。プロジェクト履歴に保存するためには、変更をスクリプトとして再現しなければならず、プロシージャの差分をマージして正しく追跡するのが難しい場合がある。
- ストアドプロシージャのエラーは、アプリケーションIDEでのコンパイルやビルドのステップの一部として捕らえることができない。ストアドプロシージャが行方不明になったり、誤って削除されたりした場合も同様である。
- ストアドプロシージャ言語は、ベンダーによって洗練されたレベルが異なる。
  - 例えば、PostgresのpgpsqlはMicrosoftのT-SQLよりも多くの言語機能(特に拡張機能による)を持っている。
- ストアドプロシージャの作成とデバッグのためのツールサポートは、他のプログラミング言語ほど充実していないことが多いが、これはベンダーや言語によって異なる。
  - 例えば、PL/SQLとT-SQLには専用の IDE とデバッガがある。PL/PgSQLは、様々なIDEからデバッグすることができる。