ストアドプロシージャとコードでSQLを維持する場合の長所と短所は何ですか[完了]


274

SQLをC#ソースコードまたはストアドプロシージャに保持することの利点/欠点は何ですか?私は私たちが取り組んでいるオープンソースプロジェクト(C#ASP.NETフォーラム)で友人とこれについて話し合っています。現時点では、ほとんどのデータベースアクセスは、SQLをC#でインラインで構築し、SQL Server DBを呼び出すことによって行われます。したがって、私は、この特定のプロジェクトに最適なものを確立しようとしています。

これまでのところ:

コードの利点:

  • 保守が容易-クエリを更新するためにSQLスクリプトを実行する必要はありません
  • 別のDBへの移植が容易-移植するprocがない

ストアドプロシージャの利点:

  • パフォーマンス
  • 安全保障

50
ストアドプロシージャを使用すると、メンテナンスが容易になると主張することもできます。1つのクエリを変更するためだけにアプリケーション全体を再デプロイする必要はありません。
Darren Gosbell、2008年

27
@GvS:これは会社の機能不全であり、ベストプラクティスではありません。もちろん、1か所で1000を変更するよりも簡単です。DBAは、システムに対する無頓着な変更を防ぐために単にその役割を果たしているだけなので、それを尊重する必要があります。
Jeremy Holovacs

回答:


179

私はストアドプロシージャのファンではありません

ストアドプロシージャは、次の理由により、より保守しやすくなっています。* SQLを変更するたびにC#アプリを再コンパイルする必要がない

とにかく、データ型が変更されたり、追加の列などを返したりする場合は、再コンパイルすることになります。アプリの下からSQLを「透過的に」変更できる回数は、全体としてかなり少ない

  • SQLコードを再利用することになります。

C#を含むプログラミング言語には、関数と呼ばれる驚くべき機能があります。つまり、同じコードブロックを複数の場所から呼び出すことができます。すごい!次に、再利用可能なSQLコードをこれらの1つに配置できます。または、本当にハイテクにしたい場合は、それを行うライブラリを使用できます。それらはオブジェクトリレーショナルマッパーと呼ばれ、最近ではかなり一般的です。

コードの繰り返しは、メンテナンス可能なアプリケーションを構築しようとしているときにできる最悪のことです。

同意します。これが、storedprocが悪いことである理由です。コードを関数にリファクタリングおよび分解(小さな部分に分解)する方が、SQLにブロックするよりもはるかに簡単です... SQLのブロックですか?

同じSQLコードを使用する4つのWebサーバーと多数のWindowsアプリがあります。SQlコードに小さな問題があることに気付いたので、むしろprocを1か所で変更するか、コードをすべてにプッシュします。ウェブサーバー、すべてのウィンドウボックスにすべてのデスクトップアプリを再インストールします(クリックすると解決する場合があります)

Windowsアプリが中央データベースに直接接続しているのはなぜですか?それはまさに巨大なセキュリティホールのようであり、サーバー側のキャッシュを除外する際のボトルネックになっています。彼らはウェブサービスまたはあなたのウェブサーバーと同様のものを介して接続すべきではありませんか?

では、1つの新しいsproc、または4つの新しいWebサーバーをプッシュしますか?

この場合、1つの新しいsprocをプッシュする方簡単ですが、私の経験では、「プッシュされた変更」の95%はデータベースではなくコードに影響します。その月に20個をWebサーバーにプッシュし、1個をデータベースにプッシュする場合、代わりに21個をWebサーバーにプッシュし、ゼロをデータベースにプッシュしてもほとんど損失はありません。

コードのレビューがより簡単になります。

どのように説明できますか?わかりません。特に、sprocはおそらくソース管理に含まれていないため、WebベースのSCMブラウザーなどからはアクセスできません。

その他の短所:

Storedprocはデータベース内に存在し、外部からはブラックボックスとして表示されます。ソース管理にそれらを入れたいというような単純なことは悪夢になります。

まったくの努力の問題もあります。フォーラムを構築するために700万ドルの費用がかかる理由をCEOに正当化しようとする場合、すべてを100万の階層に分解することは理にかなっているかもしれません。利益。


99

これは現在、ここの他のいくつかのスレッドで議論されています。私はストアドプロシージャの一貫した支持者ですが、LinqからSqlへの良い議論がいくつか提示されています。

コードにクエリを埋め込むと、データモデルに密接に結び付けられます。ストアドプロシージャは契約上のプログラミングの優れた形式です。つまり、ストアドプロシージャの入力と出力によって表される契約が維持されている限り、DBAはデータモデルとプロシージャのコードを自由に変更できます。

クエリがコードに埋め込まれているため、管理が容易な1つの中央にではなく、運用データベースのチューニングが非常に困難な場合があります。

[編集]ここに別の現在の議論があります


47

私の意見では、この質問に賛成か反対か投票することはできません。それは完全にあなたのアプリケーションのデザインに依存します。

私は、アプリケーションサーバーが前面にある3層環境でのSPの使用に全面的に反対します。この種の環境では、アプリケーションサーバーがビジネスロジックを実行するために存在します。さらにSPを使用すると、ビジネスロジックの実装をシステム全体に分散し始めるので、誰が何に責任を負っているかが非常に不明確になります。最終的には、基本的には次のことだけを行うアプリケーションサーバーになります。

(Pseudocode)

Function createOrder(Order yourOrder) 
Begin
  Call SP_createOrder(yourOrder)
End

したがって、最終的に、この16のCPUを搭載したこの非常にクールな4サーバークラスタで中間層を実行すると、実際には何も実行されません。なんてもったいない!

DBに直接接続する太いGUIクライアント、またはさらに多くのアプリケーションがある場合、それは別の話です。この場合、SPは、アプリケーションをデータモデルから切り離し、制御可能なアクセスを提供する、一種の疑似中間層として機能します。


44

コードの利点:

  • 保守が容易-クエリを更新するためにSQLスクリプトを実行する必要はありません
  • 別のDBへの移植が容易-移植するprocがない

実際、あなたはそれを逆に持っていると思います。私見、コード内のSQLを維持するのは面倒です。

  • あなたは関連するコードブロックで自分自身を繰り返すことになります
  • SQLは多くのIDEの言語としてサポートされていないので、タスクを実行するエラーチェックされていない一連の文字列しかありません。
  • データ型、テーブル名、または制約の変更は、データベース全体を新しいものに交換するよりもはるかに一般的です
  • クエリが複雑になるにつれて、難易度が高くなります
  • インラインクエリをテストするには、プロジェクトをビルドする必要があります

ストアドプロシージャは、データベースオブジェクトから呼び出すメソッドと考えてください。再利用がはるかに簡単です。編集する場所は1つだけで、DBプロバイダーを変更した場合、変更はストアドプロシージャで発生し、コードでは発生しません。 。

つまり、Stuが私の前に言ったように、ストアドプロシージャのパフォーマンスの向上は最小限であり、ストアドプロシージャにブレークポイントを設定することはできません(まだ)。


33

CON

ストアドプロシージャ内で多くの処理を行うと、行為のスケーリングに関して、DBサーバーが柔軟性のない単一のポイントになることがわかりました。

ただし、sql-serverと対照的に、プログラム内ですべての処理 を実行すると、コードを実行するサーバーが複数ある場合に、より多くのスケーリング可能になる場合があります。もちろん、これは通常のフェッチまたは更新のみを行うストアドプロシージャには適用されず、データセットのループ処理などのより多くの処理を実行するストアドプロシージャには適用されません。

長所

  1. 価値のあるパフォーマンス(DBドライバーによるクエリ解析やプランの再作成などを回避)
  2. データ操作はC / C ++ / C#コードに埋め込まれていません。つまり、調べる低レベルのコードが少なくなっています。個別に記載すると、SQLは冗長ではなくなり、簡単に確認できます。
  3. 分離されているため、SQLコードを簡単に見つけて再利用できます。
  4. スキーマが変更されたときに物事を変更する方が簡単です-コードに同じ出力を与えるだけで問題なく機能します
  5. 別のデータベースへの移植が容易になります。
  6. ストアドプロシージャの個々のアクセス許可を一覧表示し、そのレベルでアクセスを制御することもできます。
  7. データクエリ/永続化コードをデータ変換コードとは別にプロファイルできます。
  8. ストアドプロシージャに変更可能な条件を実装でき、顧客サイトで簡単にカスタマイズできます。
  9. いくつかの自動化ツールを使用して、スキーマとステートメントを一緒に変換する方が、コード内に埋め込む必要がある場合よりも簡単に変換できます。
  10. すべてのデータアクセスコードが1つのファイル内にあると、データアクセスのベストプラクティスをより簡単に保証できます-パフォーマンスの低いテーブルにアクセスするクエリ、またはより高いレベルのシリアル化を使用するクエリ、またはコードで*を選択するクエリを確認できます。
  11. すべてが1つのファイルにリストされていると、スキーマの変更/データ操作ロジックの変更を見つけやすくなります。
  12. SQLの編集が同じ場所にあると、すべてのストアドプロシージャのトランザクション分離ステートメントを変更/追加するなど、SQLの検索と置換の編集が容易になります。
  13. 私とDBAの担当者は、DBAが私のSQL内容を確認する必要がある場合に、個別のSQLファイルを使用する方が簡単/便利であることに気付きました。
  14. 最後に、チームの一部の怠惰なメンバーが埋め込みSQLを使用するときにパラメーター化されたクエリを使用しなかったため、SQLインジェクション攻撃について心配する必要はありません。

22

ストアドプロシージャのパフォーマンス上の利点は、ほとんど無視できます。

ストアドプロシージャのその他の利点:

  • リバースエンジニアリングを防止する(もちろん、暗号化を使用して作成した場合)
  • データベースアクセスの一元化
  • データモデルを透過的に変更する機能(新しいクライアントを展開する必要なし)。複数のプログラムが同じデータモデルにアクセスする場合に特に便利

16

私はコード側に落ちます。すべてのアプリ(Webとクライアントの両方)で使用されるデータアクセスレイヤーを構築するため、その観点から見るとDRYです。テーブルスキーマが正しいことを確認するだけでよいので、データベースの展開が簡素化されます。ソースコードやデータベースを確認する必要がないため、コードのメンテナンスが簡単になります。

データモデルとの密結合については、それほど問題になりません。結合を実際に解除できる場所がわからないからです。アプリケーションとそのデータは本質的に結合されています。


13

ストアドプロシージャ。

エラーがスリップしたり、ロジックが少し変わった場合、プロジェクトを再コンパイルする必要はありません。さらに、プロジェクトでクエリをコーディングした場所だけでなく、さまざまなソースからのアクセスが可能です。

ストアドプロシージャを維持することは難しくないと思います。データベースで直接コーディングするのではなく、最初に別のファイルでコーディングする必要があります。そうすれば、セットアップする必要のあるDBでそれらを実行できます。


24
コードの再コンパイルを回避するために基本的なアーキテクチャ上の決定を行っていることに気付いた場合は、何もする前に、まったく問題のないビルドプロセスを確立してください。これは引数ではありません。
Michael Borgwardt

13

ストアドプロシージャの利点

コードのレビューがより簡単になります。

結合が少ないため、テストが簡単です。

より簡単に調整できます。

ネットワークトラフィックの観点から見ると、一般的にパフォーマンスは優れています。カーソルなどがある場合、データベースへの複数のトリップはありません。

データへのアクセスをより簡単に保護し、テーブルへの直接アクセスを削除し、プロシージャを介してセキュリティを適用できます。これにより、テーブルを更新するコードを比較的すばやく見つけることもできます。

他のサービス(レポートサービスなど)が含まれている場合、すべてのロジックをコードではなくストアドプロシージャに格納する方が簡単で、複製する必要がある場合があります。

短所:

開発者にとって管理が難しい:スクリプトのバージョン管理:誰もが独自のデータベースを持っていますか?バージョン管理システムはデータベースとIDEに統合されていますか?


はい、Visual Studio 2012データベースプロジェクトとTFSのストアドプロシージャとデータベースにバージョンコントロールを含めることができます。
ハジラジン2013年

11

状況によっては、コードで動的に作成されたSQLは、ストアドプロシージャよりもパフォーマンスが優れている場合があります。非常に柔軟でなければならないため、数十のパラメーターで非常に複雑になるストアドプロシージャ(sp_customersearchとしましょう)を作成した場合、実行時にコードではるかに単純なSQLステートメントを生成できます。

これは単にSQLからWebサーバーに処理を移動するだけだと主張することもできますが、一般的にはそれで十分です。

この手法のもう1つの優れた点は、SQLプロファイラーを使用している場合、生成したクエリを確認し、20個のパラメーターを持つストアドプロシージャコールが表示されるよりもはるかに簡単にデバッグできることです。


1
なぜこの回答が否決されたのかはわかりません。小さいクエリの方がパフォーマンスが良いのは事実です。これは、SQL Serverチームからもコメントされています。
ブラノン

9

私はストアドプロシージャが好きですが、アプリケーションにダウンタイムを発生させなかったストアドプロシージャを使用してアプリケーションに変更を加えることができた回数を知りません。

Transact SQLの大ファンである大規模なクエリのチューニングは、私にとって非常に有用であることが証明されています。インラインSQLを約6年も書いていない!


コードでクエリを使用して別の視点を理解できない、理解できない...
Chaki_Black

8

sprocの2つのプロポイントをリストします。

パフォーマンス-それほどではありません。SQL 2000以降では、クエリプランの最適化はかなり良く、キャッシュされています。Oracleなどでも同様のことができると思います。パフォーマンスのためのsprocsのケースはもうないと思います。

セキュリティ?なぜsprocはより安全なのでしょうか?とにかくセキュリティ保護されていないデータベースがない限り、すべてのアクセスはDBAから、またはアプリケーションを介して行われます。常にすべてのクエリをパラメーター化します。ユーザー入力から何かをインライン化しないでください。問題はありません。

それはとにかくパフォーマンスのベストプラクティスです。

Linqは間違いなく、今私が新しいプロジェクトに取り組む方法です。この同様の投稿を参照してください。


アドホックSQL実行プランは特定の状況でのみ再利用されます:tinyurl.com/6x5lmd [SOはコードを証明して回答] SQLへのLINQは正式に無効になりましたtinyurl.com/6298nd [ブログ投稿]
HTTP 410

1
プロシージャは、最も安全な方法です。これらは、ユーザーがプロシージャでアクションを実行することだけを制限します。書き込みアクセス権があるテーブルやビューに直接アクセスして、変更することはできません。内部の脅威による害を防ぐために、プロシージャが必要です。
HLGEM、2011

8

@キース

セキュリティ?なぜsprocsの方が安全ですか?

Komradekatzによって提案されているように、テーブルへのアクセスを許可せず(DBに接続するユーザー名とパスワードの組み合わせ)、SPアクセスのみを許可することができます。そうすれば、誰かがデータベースのユーザー名とパスワードを取得した場合、SPを実行できますが、テーブルやDBの他の部分にはアクセスできません。

(もちろん、sprocを実行すると、必要なすべてのデータが提供されますが、利用可能なsprocによって異なります。テーブルへのアクセスを許可すると、すべてにアクセスできるようになります。)


1
@Joe Philllips、ビューはprocのセキュリティを向上させることも同等にすることもせず、詐欺や内部の害の防止には役立ちません。プロシージャを使用する場合、セキュリティモデルは、ユーザーがテーブルまたはビューではなくプロシージャへのアクセスのみを取得するため、プロシージャが行うこと以外は何も実行できません。財務データがあり、プロシージャを使用していない場合、システムが危険にさらされています。
HLGEM、2011

7

このように考える

同じSQLコードを使用する4つのWebサーバーと多数のWindowsアプリがあります。SQlコードに小さな問題があることに気付いたので、むしろprocを1か所で変更するか、コードをすべてにプッシュします。ウェブサーバー、すべてのウィンドウボックスにすべてのデスクトップアプリを再インストールします(クリックすると解決する場合があります)

私はストアドプロシージャを好む

また、プロシージャに対してパフォーマンステストを実行する方が簡単です。クエリアナライザに設定して、set showplan_text onおよびvoilaの統計io / timeを設定します。

呼び出されているものを正確に確認するためにプロファイラーを実行する必要はありません

ちょうど私の2セント


6

私はそれらをコード内に保持することを好む(インラインまたはアドホックではなくORMを使用)ので、.sqlファイルの保存に対処する必要なくソース管理でカバーできます。

また、ストアドプロシージャは本質的に安全ではありません。インラインと同じくらい簡単に、sprocを使用して不適切なクエリを記述できます。パラメータ化されたインラインクエリは、sprocと同じくらい安全です。


6

アプリのコードを最も効果的な方法として使用します。それはロジックの処理です。
データベースを使用して、データを保存します。

ストアドプロシージャをデバッグできますが、ロジックをコードでデバッグおよび保守する方が簡単です。通常、データベースモデルを変更するたびに、コードの再コンパイルを終了します。

また、オプションの検索パラメーターを持つストアドプロシージャは、すべての可能なパラメーターを事前に指定する必要があるため、非常に非効率的です。また、検索でパラメーターが繰り返される回数を予測できないため、複雑な検索ができない場合もあります。


2
複数のアプリが同じデータベースにアクセスし、データベースがインポートやその他の直接アクセスの影響を受ける場合(すべての価格を10%更新)、ロジックはデータベース内にある必要があります。そうしないと、データベースの整合性が失われます。
HLGEM 2008

複数のアプリの場合、ロジックをすべてのアプリで使用されるライブラリに配置すると、ロジックをアプリ言語で維持しながら整合性を維持できます。インポート/直接アクセスの場合、アプリに適用されるルールを適用する必要があるかどうかは、状況によって異なります。
Dave Sherohman、2008年

3
複数のアプリがデータベースに同じタイプの変更を加えることはできません。1つのタイプの変更を処理する1つのアプリコンポーネントが必要です。次に、他のユーザーが関心を持っている場合、そのアプリはサービスを公開します。複数のアプリが適切な方法で同じデータベース/テーブルを変更すると、アプリのシステムとデータベースがメンテナンスできなくなります。
Jiho Han

2
「1種類の変更を処理する1つのアプリコンポーネントが必要です」-そのコンポーネントは、PL / SQLなどのストアドプロシージャである可能性があります。
RussellH 2010年

6

セキュリティに関しては、ストアドプロシージャの方がはるかに安全です。とにかく、すべてのアクセスはアプリケーションを介して行われると主張する人もいます。多くの人々が忘れていることは、ほとんどのセキュリティ侵害は会社の内部から発生するということです。アプリケーションの「隠された」ユーザー名とパスワードを知っている開発者の数を考えてみてください。

また、MatthieuFが指摘したように、アプリケーション(デスクトップサーバーでもWebサーバーでも)とデータベースサーバーの間のラウンドトリップが少ないため、パフォーマンスが大幅に向上します。

私の経験では、ストアドプロシージャによるデータモデルの抽象化により、保守性も大幅に向上します。過去に多くのデータベースを維持しなければならなかった人として、必要なモデルの変更に直面すると、ストアドプロシージャを1つまたは2つ変更するだけで、外部のすべてのアプリケーションに対して変更を完全に透過的にすることができるので、とても安心です。多くの場合、アプリケーションはデータベースを指す唯一のものではありません。他のアプリケーション、レポートソリューションなどがあります。そのため、影響を受けるすべてのポイントを追跡するのは、テーブルへのオープンアクセスの面倒です。

また、SQLプログラミングを専門とする人の手に渡るように、またSPがコードの分離とテスト/最適化をはるかに容易にするために、plus列にチェックを入れます。

私が目にする1つの欠点は、多くの言語ではテーブルパラメータの受け渡しが許可されていないため、不明な数のデータ値を渡すのは面倒な場合があり、一部の言語では単一のストアドプロシージャから複数の結果セットを取得できない場合があります(ただし、後者は、その点でインラインSQLよりもSPを悪化させることはありません)。


モデルが変更されると、通常、sprocsを使用しているか動的SQLを使用しているかに関係なく、コードも変更する必要があります。また、テーブル/スキーマを作成したら、どのくらいの頻度でテーブル/スキーマのみを変更しますか?しばしばあるわけではない。通常、変更は別の列または別のテーブルを追加する必要があるビジネスから発生します。その場合、コードを変更せずに実行できるとは思えません。
ハンジホ

4

私が参加したセキュリティに関するMicrosoft TechEdセッションからの提案の1つ。ストアドプロシージャを介してすべての呼び出しを行い、テーブルへの直接アクセスを拒否します。このアプローチは、追加のセキュリティを提供するものとして請求されました。セキュリティのためにそれだけの価値があるかどうかはわかりませんが、すでにストアドプロシージャを使用しているのであれば、害はありません。


特に個人情報や財務情報に注意を払う場合は、データセキュリティが重要です。ほとんどの詐欺は内部関係者によって行われます。内部統制を迂回するために必要なアクセス権を彼らに与えたくないでしょう。
HLGEM 2008

4

ストアドプロシージャに配置すると、メンテナンスが間違いなく簡単になります。将来的に変更される可能性のある難しいロジックが含まれている場合は、複数のクライアントが接続しているときにデータベースに配置することをお勧めします。たとえば、私は現在、エンドユーザーのWebインターフェイスと管理デスクトップアプリケーションを備えたアプリケーションに取り組んでいます。どちらも(明らかに)データベースを共有しており、可能な限り多くのロジックをデータベースに保持しようとしています。これは、DRY原理の完璧な例です。


4

私は、ストアドプロシージャで動的SQLをだまして使用しないことを前提として、ストアドプロシージャの側にしっかりと取り組んでいます。まず、ストアドプロシージャを使用すると、dbaはテーブルレベルではなく、ストアドプロシージャレベルで権限を設定できます。これは、SQLインジェクション攻撃に対抗するだけでなく、内部関係者がデータベースに直接アクセスして変更することを防ぐために重要です。これは詐欺を防ぐのに役立つ方法です。個人情報(SSN、クレジットカード番号など)を含むデータベース、またはとにかく金融取引を作成するデータベースには、ストアリングされた手順を使用しない限りアクセスしないでください。他の方法を使用する場合、偽の金融取引を作成したり、個人情報の盗用に使用できるデータを盗んだりするために、データベースを社内の個人に広く公開しておきます。

ストアドプロシージャは、アプリから送信されるSQLよりも保守とパフォーマンスのチューニングがはるかに簡単です。また、データベースの構造変更がデータへのアクセス方法に与える影響をdbaが確認できるようにします。データベースへの動的アクセスを許可する良いdbaに会ったことはありません。


4

私が現在作業しているOracle DBでストアドプロシージャを使用しています。Subversionも使用します。すべてのストアドプロシージャは.pkbおよび.pksファイルとして作成され、Subversionに保存されます。以前にインラインSQLを実行したことがあり、それは面倒です!私はここでそれを行う方法を非常に好みます。新しいストアドプロシージャの作成とテストは、コードで行うよりもはるかに簡単です。

あります


3

小さいログ

言及されていないストアドプロシージャのもう1つのマイナーなプロ:SQLトラフィックに関しては、spベースのデータアクセスははるかに少ないトラフィックを生成します。これは、分析とプロファイリングのためにトラフィックを監視するときに重要になります。ログははるかに小さく、読みやすくなります。


3

私はストアドプロシージャの大ファンではありませんが、1つの条件で使用します。

クエリが非常に大きい場合は、コードから送信するのではなく、ストアドプロシージャとしてデータベースに保存することをお勧めします。そうすれば、アプリケーションサーバーからデータベースに大量の文字列文字を送信する代わりに、"EXEC SPNAME"コマンドのみが送信されます。

データベースサーバーとWebサーバーが同じネットワーク上にない場合(インターネット通信など)、これはやりすぎです。そうでない場合でも、ストレスが多すぎると、帯域幅が無駄になります。

しかし、男は、彼らが管理するのはとてもひどいです。できる限り避ける。


3

SQLストアドプロシージャはクエリのパフォーマンスを向上させません


それはどうしてできないのですか?これについて説明してください。
Sandesh 2014年

SQLクエリをコンパイルできる場合は、パフォーマンスが向上します。
TT。

3

ストアドプロシージャを使用すると、コードでSQLを構築するよりもいくつかの利点があります。

  1. コードの実装とSQLは互いに独立します。
  2. コードが読みやすくなります。
  3. 一度書いて何度も使います。
  4. 一度変更
  5. データベースに関するプログラマーに内部の詳細を提供する必要はありません。など

コードの問題や新機能についての情報が少ないことが私にとって有益であるような状況に行ったことはありません。5つ目を明確にしていただけませんか。
OpenCoderX 2013年

2

ストアドプロシージャは、次の理由により、より保守しやすいです。

  • SQLを変更するたびにC#アプリを再コンパイルする必要はありません
  • SQLコードを再利用することになります。

コードの繰り返しは、メンテナンス可能なアプリケーションを構築しようとしているときにできる最悪のことです。

複数の場所で修正する必要がある論理エラーを見つけた場合はどうなりますか?コードをコピーして貼り付ける最後の場所を変更するのを忘れがちです。

私の意見では、パフォーマンスとセキュリティの向上はプラスです。安全でない/非効率的なSQLストアドプロシージャを作成することはできます。

別のDBへの移植が容易-移植するprocがない

別のDBで作成するためにすべてのストアドプロシージャをスクリプト化することはそれほど難しくありません。実際、心配する必要のある主キー/外部キーがないため、テーブルをエクスポートするより簡単です。


注:「別のDBへの移植が容易-移植するprocがない」とは、別のインストールだけでなく、別のDBMSへの移植を指します。そこに選択肢があります、あなたは知っています;-)。
sleske 2009

2

@Terrapin-sprocsは、インジェクション攻撃に対して同様に脆弱です。私の言ったように:

常にすべてのクエリをパラメーター化します。ユーザー入力から何かをインライン化しないでください。問題はありません。

これはsprocsと動的SQLに当てはまります。

アプリを再コンパイルしないことが利点かどうかはわかりません。つまり、とにかく再びライブになる前に、そのコード(アプリケーションとDBの両方)に対してユニットテストを実行しました。


@Guy-はい、そうです。sprocsを使用すると、アプリケーションユーザーを制御して、基になるアクションではなくsprocのみを実行できるようにすることができます。

私の質問は次のとおりです:アプリを介したすべてのアクセス、更新および挿入などの制限された権限を持つ接続とユーザーを使用する場合、この追加のレベルはセキュリティまたは追加の管理を追加しますか?

私の意見は非常に後者です。彼らがアプリケーションを改ざんできる程度にアプリケーションを危険にさらした場合、彼らは他にもたくさんの攻撃を仕掛けることができます。

SQLインジェクションは、動的にコードをインライン化する場合、これらのsprocに対して引き続き実行できるため、ゴールデンルールが引き続き適用され、すべてのユーザー入力を常にパラメーター化する必要があります。


戦う必要のある攻撃の外側だけではありません。不正を犯すためにデータを変更する可能性があるユーザーに、テーブルへの直接アクセスを許可することはできません。
HLGEM 2008

ポリシーとして、ストアドプロシージャは動的SQLの使用を許可されるべきではありません。それを探す場合、ほとんどの場合、非動的ソリューションがあります。
HLGEM 2008

動的コードは(静的コードとは異なり)所有者のアクセス許可ではなく、呼び出し元のアクセス許可で実行されるため、SQLインジェクションは動的にインライン化されたコードを持つsprocに対してはあまり効果的ではありません。これはSQL Serverにも当てはまります-Oracleについてはわかりません。
HTTP 410

2

私がこれまで言及していないことは、データベースを最もよく知っている人が、アプリケーションコードを書く人とは限りません。ストアドプロシージャを使用すると、SQLについてあまり知りたくないプログラマとやり取りすることができます。大規模な、特にレガシーデータベースは、完全に理解するのが最も簡単なものではないため、プログラマーは必要なものを提供する単純なインターフェースを好むかもしれません。DBAが17のテーブルを結合してそれを実現する方法を理解させましょう。

とはいえ、ストアドプロシージャの記述に使用される言語(PL / SQLは悪名高い例です)は非常に残忍です。それらは通常、今日の人気のある命令型、OOP、または関数型言語で見られるような優れた機能を提供しません。COBOLを考えてください。

したがって、ビジネスロジックを含むものではなく、単にリレーショナルの詳細を抽象化するストアドプロシージャを使用してください。


「ストアドプロシージャの記述に使用される言語(PL / SQLは悪名高い例です)は非常に残忍であり、今日の人気のある言語で見られるような優れた機能を提供していません。」PL / SQLドキュメントを再読する必要があります(download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/toc.htm)。PL / SQLは、パッケージを使用したカプセル化、オブジェクトタイプによるOOP、例外処理、コードの動的実行、デバッガー、プロファイラーなどに加えて、HTTP呼び出しから暗号化や正規表現まですべてを実行するためのOracleが提供する何百もの標準パッケージ/ライブラリーを備えています。PL / SQLには多くの優れた点があります。
ObiWanKenobi 2009

2

私は通常、OOコードを記述します。ほとんどの人もおそらくそうしているのではないでしょうか。そのコンテキストでは、SQLクエリを含むすべてのビジネスロジックがクラス定義に属していることは明らかです。ロジックの一部をオブジェクトモデルに配置し、一部をデータベースに配置するようにロジックを分割することは、ビジネスロジックをユーザーインターフェイスに配置することと同じです。

以前の回答では、ストアドプロシージャのセキュリティ上の利点について多くのことが述べられています。これらは、次の2つのカテゴリに分類されます。

1)データへの直接アクセスを制限する。これは明らかにいくつかのケースで重要であり、それに遭遇したとき、ストアドプロシージャがほとんど唯一のオプションです。私の経験では、しかし、そのような場合は規則ではなく例外です。

2)SQLインジェクション/パラメータ化クエリ。この異議は赤ニシンです。インラインSQLは、動的に生成されたインラインSQLでも、ストアドプロシージャと同じように完全にパラメーター化でき、ソルトに値する最新の言語で簡単に実行できます。ここではどちらの方法にも利点はありません。(「パラメータの使用に煩わしい開発者ではない可能性があります」は有効な異論ではありません。パラメータを使用する代わりにSQLにユーザーデータを連結することを好む開発者がチームにいる場合、最初にそれらを教育してから、それらを起動します。それがうまくいかない場合は、他の悪い、明らかに有害な習慣がある開発者と同じように。)


2

私はSPROCを超えるコードの巨大な支持者です。一番の理由は、コードを緊密に結合し続けることです。次に近いのは、多くのカスタムユーティリティを使わずにソースを制御できることです。

DALでは、非常に複雑なSQLステートメントがある場合、通常それらをリソースファイルとして含め、必要に応じてそれらを更新します(これも個別のアセンブリであり、dbごとにスワップアウトされるなど)。

これにより、更新のためにいくつかの外部アプリケーションを実行することを「忘れる」ことなく、コードとSQ​​L呼び出しが同じバージョン管理に保存されます。


テーブルへの変更を複製することを「忘れた」場合はどうでしょうか。
craigmoliver 2011

プロセスは展開の問題を解決できます。
トムアンダーソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.