MS_StoredProcedure - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- 戻る(データアクセスのいろいろ)
-
ストアドプロシージャ - Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%82%A2%E3%83%89%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3- ネットワーク・プロセス間通信が発生しないので高速。
- このため、大量データの処理に使用されることが多い。
補足(「速い」の中身): ストアド プロシージャが速いのは、
主にサーバ・クライアント間の往復(ラウンドトリップ)が減るためである。
「実行プランがコンパイル済みだから速い」と説明されることがあるが、
SQL Server ではアドホック クエリでも実行プランはキャッシュ・再利用されるため、
現在この差は決定的ではない
(SQL Server アドホック クエリ問題の監視)。一方で、以下のような副作用もある。
論点 内容 パラメータ スニッフィング 初回実行時のパラメータ値でプランが固定され、他の値で極端に遅くなることがある バージョン管理 DB 内のオブジェクトのため、アプリのソース管理から外れやすい テスト 単体テストが書きにくい 移植性 T-SQL / PL/SQL は方言差が大きく、クロスDB対応が困難 パラメータ スニッフィングの対処は
OPTIMIZE FOR/RECOMPILE/
ローカル変数への退避など。詳細は
SQL Server のオプティマイザを参照。
DBMS ごとの、ネイティブなストアド プロシージャ。
DBMS ごとの、CLR ストアド プロシージャ。
- CLR ストアド プロシージャについて
https://learn.microsoft.com/ja-jp/sql/relational-databases/clr-integration-database-objects-types-net-framework/stored-procedures/clr-stored-procedures
移行メモ(正誤): 「ODE.NET」は ODP.NET(Oracle Data Provider for .NET)の誤記。
以降の見出しも同様に読み替える。
ストアドの定義と実行。
-
SqlParameter.Directionプロパティに、
ParameterDirection列挙型の 2、3、4 を設定した際の動作を確認する。
| # | メンバー名 | 説明 |
|---|---|---|
| 1 | Input | このパラメーターは入力パラメーターです。 |
| 2 | InputOutput | このパラメーターは入力と出力の両方の機能です。 |
| 3 | Output | このパラメーターは出力パラメーターです。 |
| 4 | ReturnValue | パラメーターは、ストアド プロシージャ、組み込み関数、ユーザー定義関数などの操作からの戻り値を表します。 |
-
SqlParameter.SqlDbTypeプロパティに
以下のSqlDbType列挙型を設定した際の動作を確認する。
| # | メンバー名 | 説明 |
|---|---|---|
| 1 | Structured | テーブル値パラメーターに含まれている構造化データを指定するための特別なデータ型。 |
- 参考:テーブル値パラメタ(.NETでバッチは書けるか?)
補足(
Output/ReturnValueを読むタイミング): 出力パラメータと戻り値は、
DataReaderを閉じるまで値が入らない。
ExecuteReaderを使う場合は、読み切ってClose/Disposeした後に参照する。await using (var r = await cmd.ExecuteReaderAsync()) { while (await r.ReadAsync()) { /* ... */ } } // ← ここで閉じてから int rc = (int)cmd.Parameters["@ReturnValue"].Value;なお、
ReturnValueは T-SQL のRETURN文の値(int のみ)で、
業務上のデータを返す用途には使わない(慣例として 0 = 成功)。
値を返すなら出力パラメータか結果セットを使う。
SELECT 文を発行した回数分の結果セットが返る。
-
Visual Basic .NET を使用して複数の結果セットを返す
ストアド プロシージャの型指定されたデータセットに格納する方法
https://learn.microsoft.com/ja-jp/troubleshoot/developer/visualstudio/csharp/language-compilers/fill-typed-dataset-stored-procedure -
【VB.NET】ストアドプロシージャの複数の結果を扱う
( ソフトウェア ) - プログラム の個人的なメモ
補足:
DataReaderではNextResult()で次の結果セットへ進む。
DapperではQueryMultipleを使うと簡潔に書ける。using var multi = await cn.QueryMultipleAsync("usp_GetAll", ...); var users = await multi.ReadAsync<User>(); var depts = await multi.ReadAsync<Dept>();
- Open棟梁によるストアド実行サンプル
https://gist.github.com/daisukenishino2/a97e2017a0c683d2c858e39741b63949
補足(先頭に置く定番): T-SQL のストアド プロシージャでは、
冒頭にSET NOCOUNT ON;を置くのが定番。
「n 件処理されました」というメッセージ(DONE_IN_PROC)の送出を抑止し、
往復のオーバーヘッドを減らせる。
ただし@@ROWCOUNTを参照する場合は順序に注意が必要
(SQL Server のトリガの補足を参照)。エラー処理は
TRY...CATCHとTHROW(SQL Server 2012 以降)を使う。
トランザクションを扱う場合はSET XACT_ABORT ON;を併用すると、
エラー時にトランザクションが確実にアボートされる。
補足(最新化:SQL CLR の現状): SQL CLR は現在も利用可能だが、
以下の理由で採用のハードルが上がっている。
clr enabledは既定で 0(無効)(SQL Server の基本的な設定)- SQL Server 2017 以降は
clr strict securityが既定で有効となり、
SAFEアセンブリでも署名または信頼登録(sp_add_trusted_assembly)が必要- Azure SQL Database では SQL CLR が利用できない
正規表現などの用途は、SQL Server 2016 以降の
STRING_SPLIT/JSON_VALUE、SQL Server 2025 の正規表現関数、
あるいはアプリ側での処理で代替できることが多い。
-
Transact-SQL
- ストアド プロシージャ (データベース エンジン) | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/relational-databases/stored-procedures/stored-procedures-database-engine
- ストアド プロシージャ (データベース エンジン) | Microsoft Learn
-
PL/SQL
- ストアド・プロシージャの開発および使用
https://docs.oracle.com/cd/E16338_01/appdev.112/b56266/tdddg_procedures.htm
- ストアド・プロシージャの開発および使用
以下を参考にすると、
- SQL Server では機能の違い
- Oracle では戻り値の有・無
に依るらしい。
-
Re[2]: ストアドプロシージャとファンクションの使い分け
http://bbs.wankuma.com/index.cgi?mode=al2&namber=20155&KLOG=39 -
「PL-SQL でファンクションとストアドプロシージャの差が知りたいです。」(1) Java Solution - @IT
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=25920&forum=12 -
ストアドプロシージャとビューとユーザー定義関数 - とりあえず半歩
http://sotoattanito.hatenablog.com/entry/2015/11/10/225318 -
ストアドファンクション (stored function) とは
「分かりそう」で「分からない」でも「分かった」気になれる IT 用語辞典
https://wa3.i-3-i.info/word13123.html
補足(SQL Server での使い分け): SQL Server では
ストアド プロシージャとユーザー定義関数(UDF)で
できることが明確に違う。
ストアド プロシージャ ユーザー定義関数 SELECT内での呼び出し不可 可能 データの更新 可能 不可(副作用を持てない) 出力パラメータ 可能 不可(戻り値のみ) 動的 SQL 可能 不可 トランザクション制御 可能 不可 なお、スカラー UDF は行ごとに評価されるため性能上の罠になりやすい。
SQL Server 2019 以降は「スカラー UDF のインライン化」で
自動的に改善されるケースがあるが、
可能ならインライン テーブル値関数(RETURNS TABLE AS RETURN (...))
で書くほうが確実に速い。
BEGIN...END で囲まれた手続き型と非手続き型の SQL ステートメントを実行する。
- Transact-SQL
-
Works - BEGIN~END ブロック活用
http://kojama.la.coocan.jp/works/column/beblock.html -
BEGIN...END (Transact-SQL) | Microsoft Learn
https://learn.microsoft.com/ja-jp/sql/t-sql/language-elements/begin-end-transact-sql -
Microsoft SQL Server Japan Support Team Blog
- 変数とパラメータの違い
- DO's&DONT's #10: やらない方がいいこと – クエリの条件句で変数を参照する
-
補足(「クエリの条件句で変数を参照する」がなぜ良くないか):
ローカル変数の値はコンパイル時にはオプティマイザから見えないため、
統計情報のヒストグラムが使われず、
一律の推定値(密度ベース)で件数が見積もられる。
結果として不適切な実行プランが選ばれることがある。ストアド プロシージャのパラメータであれば値が見える
(=パラメータ スニッフィングが働く)ため、
「変数に退避してから使う」テクニックは
スニッフィングを意図的に無効化したいときの手段でもある。
つまり、状況によって良し悪しが逆転する。
- PL/SQL
- PL/SQL のサブプログラムの使用
https://docs.oracle.com/cd/E16338_01/appdev.112/b56260/subprograms.htm - How To 資料: 匿名の PL/SQL ブロックを介したデータベース表に対する BLOB データの読込み/書込み
- PL/SQL のサブプログラムの使用
各 DBMS ごとに用意されている。
-
ストアド プロシージャの実行とパラメーター、戻り値の受け渡しを行う(C# / VB.NET)
-
Using SqlParameter Direction in C#.Net with Stored Procedure - CodeProject
https://www.codeproject.com/Tips/828514/Using-SqlParameter-Direction-in-Csharp-Net-with-wi
SQL CLR
-
特集 SQL Server 2005 の新機能「SQL CLR」(前編)(1/3) - @IT
http://www.atmarkit.co.jp/fdotnet/special/sqlclr01/sqlclr01_01.html- [特集]SQL Server 2005 の新機能「SQL CLR」(前編)
SQL Server プログラミングを革新する SQL CLR とは? - [特集]SQL Server 2005 の新機能「SQL CLR」(後編)
Visual Studio 2005 で SQL CLR を実装してみる
- [特集]SQL Server 2005 の新機能「SQL CLR」(前編)
-
SQL Server 2005 を使いこなそう
- (4)SQL CLR の仕組みとメリットを理解しよう - @IT
http://www.atmarkit.co.jp/ait/articles/0605/16/news106.html - (5)SQL CLR コーディング、最初の一歩 - @IT
http://www.atmarkit.co.jp/ait/articles/0606/13/news109.html
- (4)SQL CLR の仕組みとメリットを理解しよう - @IT
-
SQL CLR を極める 3 つのコーディング・テクニック - @IT
http://www.atmarkit.co.jp/fdb/rensai/sqls05try06/sqls05try06_3.html-
Transact-SQL では困難だった複雑な計算処理や文字列操作などでは大きく力を発揮します。
そこで、今回は .NET Framework で提供される正規表現ライブラリの利用を確認してみましょう。 -
正規表現とは文字列のパターンを表現する表記法です。
文字列の検索や置換といったシーンで利用されています。
ここでは正規表現による入力値チェックを SQL CLR で実装します。
-
.NET ストアド プロシージャ
-
.NET で Oracle アプリを作ろう(5)- @IT
VB.NET で楽々 Oracle ストアド・プロシージャ作成
http://www.atmarkit.co.jp/ait/articles/0603/07/news122.html -
Oracle のストアド・プロシージャを VB/C# で記述する方法:CodeZine(コードジン)
https://codezine.jp/article/detail/1202 -
.NET ストアド・プロシージャの開発とデプロイ
https://docs.oracle.com/cd/E16338_01/appdev.112/b56266/procedures_dot_net.htm
.NET CLR ルーチン
・・・
OSS の DB では、N/A であるもよう。
| # | DBMS | サポート |
|---|---|---|
| 1 | PostgreSQL | N/A |
| 2 | MySQL | N/A |
補足(正確には): 上表は「**CLR(.NET)**ストアド プロシージャ」の
サポート有無を指しており、ストアド プロシージャ自体が無いという意味ではない。
- PostgreSQL: PL/pgSQL のほか、
PL/Python・PL/Perl・PL/v8 などの手続き型言語を追加できる
(PL/CLR に相当するものは無い)- MySQL: SQL/PSM 準拠のストアド プロシージャを持つ
Tags: 移行, データアクセス, SQL Server