ストアドプロシジャは現在でも有効な技術なのか?新人エンジニア向けに使いどころ・注意点・学び方を解説

こんにちは。ゆうせいです。

今回は、「ストアドプロシジャは現在でも有効な技術なのか?」というテーマで、新人エンジニア向けに解説します。

結論から言うと、ストアドプロシジャは現在でも有効です。

ただし、「何でもストアドプロシジャに書けばよい」という時代ではありません。

現代のWeb開発では、アプリケーション側にビジネスロジックを書くことも多く、ORM、マイクロサービス、クラウド、CI/CDなどの考え方も普及しています。

そのため、ストアドプロシジャは「古いから不要」でもなく、「速そうだから全部使う」でもありません。

大切なのは、得意な場面と苦手な場面を理解して、適切に使い分けることです。

ストアドプロシジャとは何か

ストアドプロシジャとは、データベースの中に保存しておく処理のまとまりです。

SQL Serverの公式ドキュメントでは、ストアドプロシジャは1つ以上のTransact-SQL文のグループ、または.NET Framework共通言語ランタイムメソッドへの参照として説明されています。PostgreSQLにもCREATE PROCEDUREがあり、MySQLでもストアドプログラムを含むストアドオブジェクトが扱われています。

かなり簡単に言えば、ストアドプロシジャは「データベースの中に置いておく処理ボタン」です。

たとえば、アプリケーションから毎回長いSQLを書く代わりに、データベース側に処理を登録しておきます。

アプリケーションは、その処理名を呼び出すだけです。

CALL procedure_name(parameter);

日本語で言えば、アプリケーション側から、データベースに登録済みの処理を名前と引数で呼び出すという意味です。

料理でたとえるなら、ストアドプロシジャは「厨房にある定番レシピ」です。

注文を受けるたびに、ホールスタッフが細かい調理手順を全部説明する必要はありません。

「日替わり定食をお願いします」と伝えれば、厨房では決まった手順で調理できます。

データベースも同じです。

アプリケーションから「この処理を実行して」と呼び出すと、データベース内で決められたSQL処理が実行されます。

ストアドプロシジャの簡単なイメージ

たとえば、会員IDを指定して、その会員の購入履歴を取得する処理を考えます。

アプリケーション側で毎回SQLを書く場合、次のようなイメージになります。

SELECT *
FROM orders
WHERE user_id = 1001;

日本語で言えば、ordersテーブルから、user_idが1001の注文データを取得するという意味です。

ストアドプロシジャを使う場合は、データベース側に「会員の注文履歴を取得する処理」を登録しておきます。

CALL get_user_orders(1001);

日本語で言えば、1001という会員IDを渡して、登録済みの注文履歴取得処理を呼び出すという意味です。

アプリケーション側は、細かいSELECT文を直接知らなくても、処理を呼び出せます。

この仕組みが、ストアドプロシジャの基本です。

ストアドプロシジャは現在でも有効なのか

有効です。

ただし、使う場面を選びます。

ストアドプロシジャは、データベースに近い処理、大量データを扱う処理、複数のSQLをまとめて安全に実行したい処理で力を発揮します。

一方で、画面表示の都合、頻繁に変わる業務ルール、外部API連携、複雑なドメインロジックをすべてストアドプロシジャに押し込むと、保守が難しくなることがあります。

判断説明
現在でも有効主要なリレーショナルデータベースで現在もサポートされ、業務システムでも使われる
万能ではないアプリケーション側に書いた方が保守しやすい処理も多い
設計判断が重要データベース側に置くべき処理か、アプリ側に置くべき処理かを見極める必要がある

新人エンジニアに覚えてほしいのは、「ストアドプロシジャは古い技術だから避ける」ではなく、「どこに処理を置くと保守しやすいか」を考える姿勢です。

ストアドプロシジャが向いている場面

大量データをデータベース内で処理したい場合

ストアドプロシジャは、大量のデータをデータベース内で処理したい場合に向いています。

たとえば、月次集計、請求データ作成、在庫更新、会計締め処理などです。

大量のデータをアプリケーションに持ってきてから処理すると、通信量が増えます。

データベースの中で完結できる処理なら、データを外へ持ち出さずに済みます。

倉庫でたとえるなら、倉庫の中で荷物を仕分けしてから必要な分だけ出荷するようなものです。

全部の荷物を一度オフィスへ運んでから仕分けると大変ですよね。

データも同じです。

データベース内で処理した方が自然な場合があります。

複数のSQLをひとまとまりで実行したい場合

業務処理では、1つのSQLだけで終わらないことがあります。

たとえば、注文処理では、注文テーブルへの登録、在庫数の更新、ポイント付与、履歴登録などが必要になるかもしれません。

insert_order
update_stock
insert_point_history
insert_audit_log

日本語で言えば、注文登録、在庫更新、ポイント履歴登録、監査ログ登録をまとめて行うという意味です。

こうした処理をストアドプロシジャにまとめると、データベース側で一連の流れとして管理できます。

特に、トランザクションと組み合わせると効果的です。

トランザクションとは、複数の処理を「全部成功」または「全部失敗」として扱う仕組みです。

銀行振込で考えると分かりやすいです。

Aさんの口座から1万円を引いたのに、Bさんの口座に1万円が足されなかったら大問題ですよね。

引く処理と足す処理は、セットで成功しなければなりません。

権限管理をシンプルにしたい場合

ストアドプロシジャは、権限管理に使われることもあります。

アプリケーション利用者にテーブルへの直接更新権限を与えず、決められたストアドプロシジャだけ実行させる設計です。

たとえるなら、倉庫の中を誰でも自由に歩けるようにするのではなく、受付窓口から決まった手続きだけできるようにするイメージです。

テーブルに直接触らせないことで、想定外の更新を防ぎやすくなります。

ただし、権限設計を間違えると逆に危険になります。

ストアドプロシジャを使えば自動的に安全になる、とは考えないでください。

レガシーシステムや基幹システムと相性が良い場合

企業の基幹システムでは、長年ストアドプロシジャが使われていることがあります。

販売管理、在庫管理、会計、人事給与などのシステムでは、データベース側に重要な処理が入っているケースもあります。

新人エンジニアが現場に入ると、「この処理はストアドを見てください」と言われるかもしれません。

そのとき、ストアドプロシジャを知らないと、システムの本当の動きが読めません。

新規開発で使うかどうかとは別に、既存システムを理解するための知識としても重要です。

ストアドプロシジャが向いていない場面

頻繁に変わるビジネスロジック

頻繁に変わる業務ルールをすべてストアドプロシジャに書くと、変更管理が難しくなることがあります。

たとえば、キャンペーン条件、画面ごとの表示制御、外部API連携、ユーザー体験に近い判断などです。

こうした処理は、アプリケーション側に書いた方がテスト、レビュー、デプロイ、バージョン管理をしやすい場合があります。

ストアドプロシジャは、データベースの中にあります。

そのため、アプリケーションコードと同じ感覚でGit管理や自動テストを整えていない現場では、変更履歴が追いにくくなります。

コードが見つからない。

誰が変更したか分からない。

本番だけ中身が違う。

この状態は危険です。

DB製品を将来変える可能性が高い場合

ストアドプロシジャは、データベース製品ごとに書き方が異なります。

SQL ServerならTransact-SQL、OracleならPL/SQL、PostgreSQLならPL/pgSQLなど、それぞれの文化があります。

標準SQLだけで書ける処理もありますが、実務では各DB独自の機能を使うことが多いです。

そのため、ストアドプロシジャにロジックを多く書くほど、特定のDB製品に依存しやすくなります。

この状態をベンダーロックインと呼ぶことがあります。

ベンダーロックインとは、特定の製品やサービスに強く依存して、他へ移りにくくなる状態です。

スマホの充電ケーブルが特定メーカー専用だと、別のスマホに変えるとき困りますよね。

データベースでも同じようなことが起こります。

アプリケーションとの責任分担が曖昧になる場合

ストアドプロシジャを使うときに一番危険なのは、責任分担が曖昧になることです。

アプリケーション側にもロジックがある。

データベース側にもロジックがある。

画面側にもチェックがある。

バッチにも似た処理がある。

この状態になると、どこを直せばよいか分かりにくくなります。

新人エンジニアは、次の問いを持ってください。

where_should_this_logic_live?

日本語で言えば、この処理はどこに置くべきかを考えるという意味です。

処理の置き場所は、設計そのものです。

ストアドプロシジャとSQLインジェクション

ストアドプロシジャは、セキュリティの文脈でもよく話題になります。

SQLインジェクションとは、外部から入力された文字列を悪用して、不正なSQLを実行させる攻撃です。

OWASPのSQL Injection Prevention Cheat Sheetでは、プリペアドステートメントと安全なストアドプロシジャは、SQLインジェクション防止に同程度に有効だと説明されています。一方で、ストアドプロシジャ内で危険な動的SQLを組み立てるとリスクが増える場合があるとも説明されています。

つまり、ストアドプロシジャを使えば必ず安全、ではありません。

安全なのは、パラメータを正しく使い、文字列連結でSQLを作らない設計です。

危険なイメージは次の通りです。

sql = "SELECT * FROM users WHERE name = '" + input_name + "'"

日本語で言えば、入力値をそのままSQL文字列に連結しているため、攻撃されやすい書き方です。

安全寄りの考え方は、入力値をパラメータとして扱うことです。

SELECT *
FROM users
WHERE name = parameter_name

日本語で言えば、入力値をSQL文そのものではなく、値として安全に渡す考え方です。

新人エンジニアは、「ストアドだから安全」ではなく、「パラメータ化されているから安全」と理解してください。

ストアドプロシジャと関数・ビュー・トリガーの違い

新人エンジニアが混乱しやすいのが、ストアドプロシジャ、関数、ビュー、トリガーの違いです。

種類役割たとえ
ストアドプロシジャデータベース内に保存された処理手順厨房の調理手順書
関数入力を受け取り、結果を返す処理計算機
ビューSELECT結果を仮想的な表として見せる仕組み見やすく整理された窓口
トリガーINSERTやUPDATEなどをきっかけに自動実行される処理ドアを開けたら自動で点く照明

ストアドプロシジャは、明示的に呼び出して処理を実行するものです。

関数は、値を返す用途に向いています。

ビューは、複雑なSELECTを見やすくするために使われます。

トリガーは、自動で動くため便利ですが、処理が見えにくくなりやすいので注意が必要です。

現在の開発でストアドプロシジャを使うべき判断基準

ストアドプロシジャを使うかどうか迷ったら、次の観点で判断しましょう。

判断ポイントストアドプロシジャ向きアプリケーション側向き
処理の場所データベース内で完結する外部APIや画面制御と強く関係する
データ量大量データをまとめて処理する少量データをユーザー操作ごとに扱う
変更頻度比較的安定している頻繁に仕様変更される
性能要件通信量削減やDB内処理が効くアプリ側で柔軟に制御したい
移植性特定DBに寄せても問題が少ないDB変更の可能性が高い
テスト体制DB側のテストとデプロイが整っているアプリ側の自動テストに乗せたい

この表を見ると分かる通り、正解は1つではありません。

システムの性質、チームのスキル、運用体制、性能要件によって変わります。

技術選定は、道具選びです。

包丁が便利だからといって、ネジを締めるのに包丁は使いませんよね。

ストアドプロシジャも同じです。

ストアドプロシジャのメリット

メリット説明
データベース内で処理をまとめられる複数のSQLを1つの処理として扱える
大量データ処理に向く場合があるデータをアプリケーションへ持ち出さずに処理できる
権限管理に使えるテーブルへ直接触らせず、決められた処理だけ実行させられる
共通処理を再利用できる複数アプリから同じDB処理を呼び出せる
既存システム理解に役立つ基幹システムやレガシーシステムで使われていることがある

ストアドプロシジャの強みは、データに近い場所で処理できることです。

データベースの中で完結する重い処理や、安定した共通処理には向いています。

ストアドプロシジャのデメリット

デメリット説明
ロジックが分散しやすいアプリ側とDB側の両方に処理が分かれると追いにくい
バージョン管理が甘くなりやすいGit管理やレビュー体制がないと変更履歴が不明になりやすい
DB製品に依存しやすい書き方や機能がDBごとに異なる
テストが難しくなる場合があるDB状態に依存するため、テストデータ設計が必要になる
担当者が限られやすいSQLに強い人しか保守できない状態になることがある

ストアドプロシジャを使うなら、管理方法もセットで考えてください。

作って終わりではありません。

レビュー、テスト、リリース、ロールバック、監視まで考える必要があります。

新人エンジニアが学ぶべきポイント

新人エンジニアは、ストアドプロシジャをいきなり深く極める必要はありません。

まずは、次の順番で学ぶとよいです。

順番学習内容理由
1SELECT、INSERT、UPDATE、DELETESQLの基本操作を理解するため
2JOIN、GROUP BY、HAVING実務の検索・集計で必須だから
3インデックス性能問題を理解するため
4トランザクションデータ整合性を守るため
5ストアドプロシジャDB内に処理を置く考え方を学ぶため
6実行計画SQLがどう実行されるか理解するため

ストアドプロシジャだけを単独で学ぶより、SQL、トランザクション、インデックスとセットで学んだ方が理解しやすいです。

基礎を飛ばすな。

ストアドプロシジャは、SQLの応用です!

新人エンジニア向けの実務チェックリスト

現場でストアドプロシジャを見たら、次の点を確認しましょう。

確認項目見る理由
どのアプリから呼ばれているか影響範囲を把握するため
どのテーブルを参照・更新しているかデータへの影響を理解するため
トランザクションはどう扱っているか途中失敗時の挙動を確認するため
動的SQLを使っていないかSQLインジェクションや保守性のリスクを見るため
エラー時の処理はあるか障害時に安全に止まるか確認するため
バージョン管理されているか変更履歴を追えるか確認するため
テストデータとテスト手順があるか修正後に安全確認できるか見るため

ストアドプロシジャは、見た目以上に影響範囲が広いことがあります。

安易に変更しないでください。

まず呼び出し元と更新対象を確認しましょう。

現代的にストアドプロシジャを使うなら

現代的にストアドプロシジャを使うなら、次のような運用が重要です。

ポイント説明
Gitで管理するCREATE文や変更スクリプトをコードとして管理する
レビュー対象にするアプリケーションコードと同じようにレビューする
マイグレーションに含めるDB変更と一緒にリリースできるようにする
自動テストを用意する入力データと期待結果を確認できるようにする
責任範囲を明確にするどの処理をDB側に置くかチームで決める
動的SQLを慎重に扱う文字列連結でSQLを作る場合は特に注意する

ストアドプロシジャそのものが悪いのではありません。

管理されていないストアドプロシジャが危険なのです。

アプリケーションコードも、管理されていなければ危険ですよね。

DB側の処理も同じように、コードとして扱う必要があります。

まとめ

ストアドプロシジャは、現在でも有効な技術です。

SQL Server、PostgreSQL、MySQLなどの主要なリレーショナルデータベースでも、ストアドプロシジャやストアドプログラムは現在の公式ドキュメントで扱われています。

ただし、何でもストアドプロシジャに書くべきではありません。

大量データ処理、DB内で完結する処理、トランザクションを含む定型処理、権限管理に関わる処理には向いています。

一方で、頻繁に変わる業務ロジック、外部API連携、画面都合の処理、DB製品をまたぐ可能性が高い処理には、アプリケーション側の方が向いている場合があります。

結論内容
現在でも有効か有効。ただし使いどころを選ぶ
向いている処理大量データ処理、DB内完結処理、定型バッチ、トランザクション処理
注意する処理頻繁に変わる業務ロジック、外部連携、画面都合の処理
新人が学ぶべきことSQL、トランザクション、インデックス、権限、テスト、変更管理
重要な考え方処理をどこに置くべきかを設計として考える

ストアドプロシジャは、古い技術ではなく、データベースに近い処理を扱うための今でも使える道具です。

ただし、道具は使いどころを間違えると負債になります。

新人エンジニアは、「ストアドプロシジャを使えるか」だけでなく、「なぜそこに処理を置くのか」を説明できるようになりましょう。

今後の学習では、まずSQLの基本、JOIN、集計、トランザクション、インデックスを押さえましょう。その後、簡単なストアドプロシジャを書き、アプリケーション側の処理と比較してください。さらに、Git管理、テスト、SQLインジェクション対策まで学ぶと、現場で安全に扱える力が身につきます!

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
海外放浪の末、2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。