274

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

これまでのところ、私は持っています:

コード内の利点:

  • メンテナンスが容易 - クエリを更新するために SQL スクリプトを実行する必要がない
  • 別の DB への移植が容易 - 移植する proc が不要

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

  • パフォーマンス
  • 安全
4

47 に答える 47

179

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

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

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

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

C# を含むプログラミング言語には、関数と呼ばれるこの驚くべき機能があります。つまり、同じコード ブロックを複数の場所から呼び出すことができます。すばらしい!その後、再利用可能な SQL コードをこれらのいずれかに入れることができます。または、本当にハイテクを取得したい場合は、それを行うライブラリを使用できます。それらは Object Relational Mappers と呼ばれ、最近ではかなり一般的になっていると思います。

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

これが、ストアドプロシージャが悪いことである理由です。コードを関数にリファクタリングして分解 (より小さな部分に分割) する方が、SQL を... SQL のブロックにするよりもはるかに簡単ですか?

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

Windows アプリが中央データベースに直接接続しているのはなぜですか? これは巨大なセキュリティ ホールのようであり、サーバー側のキャッシュを排除するためのボトルネックです。Web サービスなどを介して Web サーバーに接続するべきではありませんか?

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

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

より簡単にコードをレビューできます。

方法を説明できますか?わかりません。特に、sprocs はおそらくソース管理されていないため、Web ベースの SCM ブラウザーなどからアクセスすることはできません。

その他の短所:

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

純粋な努力の問題もあります。いくつかのフォーラムを構築するのに 700 万ドルかかる理由を CEO に正当化しようとしている場合は、すべてを100 万層に分割することは理にかなっているかもしれませんが、それ以外の場合は、すべての小さなものに対して storeproc を作成することは、無駄な追加作業にすぎません。利点。

于 2008-08-18T21:50:33.757 に答える
99

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

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

本番データベースのチューニングは、クエリがコードに埋め込まれており、管理しやすい 1 つの場所に集中していない場合、非常に困難になる可能性があります。

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

于 2008-08-18T20:01:58.937 に答える
47

私の意見では、この質問に賛成または反対で投票することはできません。アプリケーションの設計に完全に依存します。

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

(Pseudocode)

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

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

DB に直接接続するファットな gui クライアントがある場合、またはさらに多くのアプリケーションがある場合は、話が異なります。この状況では、SP は、アプリケーションをデータ モデルから分離し、制御可能なアクセスを提供する、ある種の疑似中間層として機能できます。

于 2008-10-23T13:27:55.693 に答える
44

コード内の利点:

  • メンテナンスが容易 - クエリを更新するために SQL スクリプトを実行する必要がない
  • 別の DB への移植が容易 - 移植する proc が不要

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

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

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

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

于 2008-08-18T20:07:42.433 に答える
33

コン

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

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

長所

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

多くの場合、ストアド プロシージャのパフォーマンス上の利点は無視できます。

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

  • リバース エンジニアリングを防止する (もちろん、暗号化を使用して作成した場合)
  • データベース アクセスの集中化の改善
  • データ モデルを透過的に変更する機能 (新しいクライアントを展開する必要はありません)。複数のプログラムが同じデータ モデルにアクセスする場合に特に便利です
于 2008-08-18T19:57:57.820 に答える
16

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

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

于 2008-08-18T20:29:35.213 に答える
13

ストアド プロシージャ。

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

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

于 2008-08-18T20:01:04.100 に答える
13

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

より簡単にコードをレビューできます。

結合が少ないため、テストが容易になります。

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

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

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

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

短所:

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

于 2008-08-18T20:35:25.810 に答える
11

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

これは単純に一部の処理を SQL から Web サーバーに移すだけだと主張する人もいるかもしれませんが、一般的にはそれは良いことです。

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

于 2008-09-05T16:01:03.500 に答える
9

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

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

于 2008-08-29T21:27:58.223 に答える
8

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

パフォーマンス - そうではありません。Sql 2000 以降では、クエリ プランの最適化は非常に優れており、キャッシュされています。Oracleなども同様のことをしていると思います。パフォーマンスのためにsprocを使用するケースはもうないと思います。

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

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

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

于 2008-08-18T20:24:53.133 に答える
8

@キース

安全?sprocs のほうが安全なのはなぜですか?

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

(もちろん、sproc を実行すると、必要なすべてのデータが得られる場合がありますが、それは利用可能な sproc によって異なります。テーブルへのアクセスを与えると、すべてにアクセスできるようになります。)

于 2008-08-18T21:12:39.933 に答える
7

このように考えてみてください

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

ストアド プロシージャの方が好き

proc に対してパフォーマンス テストを行うのも簡単です。それをクエリ アナライザーに入れ、set statistics io/time on set showplan_text on をオンにすると出来上がりです。

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

ちょうど私の2セント

于 2008-08-18T20:16:14.850 に答える
6

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

また、MatthieuF が指摘したように、アプリケーション (デスクトップまたは Web サーバー上にあるかどうか) とデータベース サーバー間の往復が少なくなるため、パフォーマンスが大幅に向上する可能性があります。

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

また、SQL プログラミングを専門とする担当者の手に委ねること、およびコードの分離とテスト/最適化をはるかに容易にする SP についても、プラスの列にチェックを入れます。

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

于 2008-09-17T14:40:22.657 に答える
6

アプリ コードを最適な状態で使用してください。つまり、ロジックを処理します。
データベースが最も得意とすること、つまりデータを保存するためにデータベースを使用します。

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

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

于 2008-08-18T22:10:49.207 に答える
6

.sql ファイルの保存に対処する必要がなく、ソース管理によってカバーされるように (インラインまたはアドホックではなく、ORM を使用して) コード内に保持することを好みます。

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

于 2008-08-18T20:01:27.237 に答える
4

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

あります

于 2008-12-08T20:22:52.543 に答える
4

ストアド プロシージャで動的 SQL をごまかしたり使用したりしないことを前提として、私はストアド プロシージャの側にいます。まず、ストアド プロシージャを使用すると、データベース管理者は、テーブル レベルではなく、ストアド プロシージャ レベルでパーミッションを設定できます。これは、SQL インジェクション攻撃に対抗するためだけでなく、インサイダーがデータベースに直接アクセスして変更を加えるのを防ぐためにも重要です。これは、詐欺を防止するのに役立つ方法です。個人情報 (SSN、クレジット カード番号など) を含むデータベースや、何らかの方法で金融取引を作成するデータベースには、ストアド プロシージャ以外でアクセスしてはなりません。他の方法を使用すると、会社内の個人が偽の金融取引を作成したり、個人情報の盗難に使用できるデータを盗んだりするために、データベースを広く開いたままにすることになります.

また、ストアド プロシージャは、アプリから送信された SQL よりもはるかに簡単に維持でき、パフォーマンスを調整できます。また、DBA は、データベース構造の変更がデータへのアクセス方法に与える影響を確認することもできます。データベースへの動的アクセスを許可する優れたデータベース管理者に会ったことがありません。

于 2008-09-28T18:47:49.800 に答える
4

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

于 2008-08-18T20:10:20.197 に答える
4

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

于 2008-08-18T20:15:39.220 に答える
3

SQL ストアド プロシージャによってクエリのパフォーマンスが向上しない

于 2011-03-24T10:43:50.150 に答える
3

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

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

より小さな丸太

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

于 2008-09-28T18:32:42.597 に答える
3

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

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

これは、データベース サーバーと Web サーバーが同じネットワーク上にない場合 (たとえば、インターネット通信) にはやり過ぎです。そうでなくても、過度のストレスは帯域幅の無駄遣いを意味します。

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

于 2010-06-08T09:15:25.903 に答える
2

私は SPROC よりもコードを強く支持しています。1 番目の理由はコードを密結合に保つことであり、2 番目に近い理由は、多くのカスタム ユーティリティを使用せずにソース管理を容易にすることです。

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

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

于 2008-10-17T22:48:11.620 に答える
2

ストアド プロシージャは、次の理由により保守性が高くなります。

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

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

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

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

別の DB への移植が容易 - 移植する proc が不要

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

于 2008-08-18T20:44:20.893 に答える
2

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

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

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

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


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

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

私の意見は非常に後者です。彼らがあなたのアプリケーションを書き直せるレベルまで侵害した場合、彼らは他にも多くの攻撃を行うことができます。

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

于 2008-08-18T21:32:57.177 に答える
2

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

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

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

于 2008-09-05T16:17:30.483 に答える
2

私は通常、オブジェクト指向のコードを書きます。おそらくあなたのほとんどもそうだと思います。そのコンテキストでは、SQL クエリを含むすべてのビジネス ロジックがクラス定義に属していることは明らかです。一部がオブジェクト モデルに存在し、一部がデータベースに存在するようにロジックを分割することは、ビジネス ロジックをユーザー インターフェイスに配置することに勝るものはありません。

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

1) データへの直接アクセスを制限する。これは場合によっては間違いなく重要であり、これに遭遇した場合は、ストアド プロシージャがほぼ唯一の選択肢となります。ただし、私の経験では、そのようなケースは規則ではなく例外です。

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

于 2008-10-23T14:30:45.363 に答える
1

LLBLGenProなどのO/Rマッパーを使用することを好みます。

これにより、データベースの移植性が比較的簡単になり、強く型付けされたオブジェクトを使用してアプリケーションと同じ言語でデータベースアクセスコードを記述できるようになります。また、私の意見では、プルバックするデータの操作方法に柔軟性があります。

実際、強く型付けされたオブジェクトを操作できることは、O/Rマッパーを使用するのに十分な理由です。

于 2008-10-02T21:12:19.763 に答える
1

誰も単体テストについて言及していません!

saveOrder メソッドがある場合、内部で複数のメソッドを呼び出して、それぞれの単体テストを作成できますが、ストア プロシージャのみを呼び出している場合は、それを行う方法はありません。

于 2014-02-18T18:11:30.803 に答える
1

SQL インジェクション攻撃は増加傾向にあります。誰かがこのコードを見つけて、Web サイトでインジェクション攻撃を実行するのは非常に簡単です。常にクエリをパラメータ化する必要があります。動的 SQL クエリで exec(@x) を実行しないことをお勧めします。インライン SQL を使用するのは良い考えではありません、IMO。

一部の人が主張しているように、ストアド プロシージャは、コードとは別に維持する別の項目のセットであるため、面倒です。しかし、それらは再利用可能であり、クエリにバグが見つかった場合は、再コンパイルせずに修正できます。

于 2008-08-19T05:44:14.220 に答える
1

ストアド プロシージャに対する私の投票。データに近い抽象化レイヤーとして、セットで効率的で、多くの「クライアント」(クライアント言語)で再利用できます。T-SQL 言語は少し原始的ですが (SO のほとんどの C# 関係者はこれに触れていると思います)、Oracle の PL/SQL は最新のプログラミング言語と同等です。

バージョン管理に関しては、バージョン管理下のテキスト ファイルにストアド プロシージャ コードを配置し、スクリプトを実行してデータベースにプロシージャを作成するだけです。

于 2008-10-27T14:12:58.963 に答える
1

他の回答で見つけられなかった1つのポイントは次のとおりです。

お使いの環境でデータベースとそのスキーマがアーキテクチャの中心であり、アプリケーションがよりサテライトの役割を持っている場合、ストアド プロシージャをより頻繁に使用することは理にかなっています。これは、アクセスする必要があるすべてのアプリケーションにレベル ベースを提供するのに役立つ場合があります。したがって、コードの繰り返しが少なくなります (たとえば、DB にアクセスするすべてのアプリケーションが常に C# または他の .NET 言語で記述されると確信していますか?)。

一方、アプリケーションがより中心的な役割を持ち、DB がアプリケーションのバッキング ストアとして機能する場合は、ストアド プロシージャの使用を減らし、共通の永続化レイヤーを提供することでコードの繰り返しを減らすことが賢明な場合があります。 、おそらくORMツール/フレームワークに基づいています。

どちらの場合も、DB がストアド プロシージャの便利なリポジトリと見なされないことが重要です。それらをバージョン管理システム内のソース ファイルに保持し、可能な限り展開を自動化してみてください (これは、実際にはすべてのスキーマ関連のアーティファクトに有効です)。

于 2011-08-19T14:43:55.593 に答える
1

セキュリティを強化するために、基になるテーブルへの直接アクセスを制限する方法として、ストアド プロシージャを使用することに別の票を投じたいと思います (メンテナンスとバージョン管理に関しては、ストアド プロシージャが導入する手間がかかりますが)。

于 2008-08-19T19:25:17.933 に答える
1

ストアド プロシージャは、アプリケーションとデータベースの間に立つために使用される場合、最悪です。上記の使用理由の多くは、ビューによってより適切に処理されます。

セキュリティの議論は偽りです。セキュリティの問題をアプリケーションからデータベースに移すだけです。コードはコード。アプリケーションから SQL を取り込み、それを使用して SQL インジェクション攻撃を受けるクエリを作成するストアド プロシージャを見てきました。

一般に、彼らはいわゆるデータベース開発者といわゆるアプリケーション開発者との間に溝を作る傾向があります。実際には、記述されるコードはすべてアプリケーション コードであり、実行コンテキストの違いにすぎません。

LINQ、Rails ActiveRecord、Hibernate/NHibernate などの豊富な SQL 生成ライブラリを使用すると、開発が高速化されます。ミックスにストアド プロシージャを挿入すると、速度が低下します。

于 2008-09-27T02:49:34.353 に答える
1

@キース

安全?sprocs のほうが安全なのはなぜですか?

ストアド プロシージャは、SQL インジェクション攻撃に対する本質的な保護を提供します。

ただし、このような攻撃に対して脆弱なストアド プロシージャ (つまり、ストアド プロシージャ内の動的 SQL) を作成できるため、完全に保護されているわけではありません。

于 2008-08-18T20:51:16.323 に答える
0

ストアドプロシージャの長所1)。ストアドプロシージャのSQLは本質的に静的であるため、セキュリティが向上します(ほとんどの場合)。これにより、SQLインジェクションから保護されます。2)。再利用性。複数のアプリケーション/コンポーネントに対して同じデータを返す必要がある場合は、SQLステートメントを繰り返すのではなく、これを選択することをお勧めします。3)。クライアントとデータベースサーバー間の呼び出しを減らします。

他のデータベースについてはよくわかりませんが、メインフレーム上のdb2でホスト言語のストアドプロシージャを作成できるため、非常に強力です。

于 2009-04-16T17:44:51.533 に答える
0

私が働いている場所でのsprocの最大の利点は、時が来たときにVB.NET(VB6から)に移植するコードがはるかに少ないことです。また、すべてのクエリにsprocを使用するため、コードが大幅に削減されます。

また、VBコードを更新する代わりにクエリを更新し、再コンパイルしてすべてのコンピューターに再インストールする必要がある場合にも、非常に役立ちます。

于 2012-10-02T13:18:28.203 に答える
0

ソース管理でストアド プロシージャを簡単に維持し、コード ベースと同じくらいシームレスにする良い方法をまだ見つけていません。それは起こりません。これだけでも、SQL をコードに入れる価値があります。最新のシステムでは、パフォーマンスの違いはごくわずかです。

于 2008-09-25T08:00:41.480 に答える
0

ストアド プロシージャは、コードよりも簡単に、データベースとソース管理システムの間で非同期になる可能性があります。アプリケーション コードでも可能ですが、継続的インテグレーションを使用している場合は可能性が低くなります。

データベースがそうであるように、人々は必然的に実稼働データベースに変更を加えます。次に、環境とソース管理システム全体で同期することを忘れてください。遅かれ早かれ、実稼働データベースはソース管理システムではなく事実上のレコードになります。使用されているかどうかがわからないため、sproc を削除できない状況になります。

ソース管理システム (sans data) からデータベースをゼロから再構築できるように、適切なプロセスでのみ本番環境への変更を許可する必要があります。しかし、私が言っているのは、それが可能であり、実際に行われているという理由だけです。変更は、顧客からの電話の合間に、マネージャーが首をかしげるなどの瞬間に行われます。

アドホック クエリの実行は、ストアド プロシージャでは厄介です。動的 SQL (または ORM) を使用すると簡単に実行できます。これは、ストアド プロシージャを使用することの最大の欠点かもしれません。

一方、ストアド プロシージャは、変更を加えるがアプリ コードの再デプロイを必要としない場合に適しています。また、ネットワーク経由でデータを送信する前に、データを整形することもできます。コード内の SQL は、データを整形するよりも取得するために複数の呼び出しを行う必要がある場合があります (ただし、複数の SQL ステートメントを実行し、単一の "呼び出しで複数の結果セットを返す方法があります)。 "、ADO.NET の MARS のように)、おそらくより多くのデータがネットワークを通過することになります。

ただし、パフォーマンスとセキュリティに関する他の議論は受け付けていません。良いことも悪いこともあり、同じように制御されます。

于 2010-02-27T18:08:05.763 に答える
0

プログラマーはアプリにコードが必要です。DBA はそれをデータベースに入れたいと思っています。

両方ある場合は、ストアド プロシージャを使用して作業を 2 つに分割することができ、プログラマーはこれらすべてのテーブルがどのように結合されるかなどについて心配する必要はありません (申し訳ありませんが、すべてを制御したいことはわかっています)。 .

データベースのビューまたはストアド プロシージャでカスタム レポートを作成できるサード パーティ アプリケーションがあります。すべてのロジックを別のアプリケーションのコードに入れると、再利用できなくなります。データベースを使用してすべてのアプリを作成する状況にある場合、これは問題ではありません。

于 2009-06-15T13:56:21.380 に答える
0

プログラミング言語とアプリケーション フレームワークは次のようになります。

  • 高レベル、特に SQL との比較
  • 特にSQLと比較して、自動化されたプロセスを介してバージョン管理と展開が容易

これら 2 つの条件が 2 つの場合は、ストアド プロシージャをスキップします。

于 2010-11-06T06:38:16.123 に答える
0

ストアド プロシージャが好まれる理由: - システムの実行中に本番環境でのデータ関連の問題を修正できるようにする (これは私にとって 1 つ目です) - DB とプログラムの間の明確なコントラクト定義 (問題の明確な分離) - 異なる DB ベンダーへのより優れた移植性 (コードの変更よりも適切に記述されている場合、通常は SP 側でのみ変更されます)。- パフォーマンス チューニングのためのより良い位置付け

短所 - WHERE 句の使用条件に大きなばらつきがあり、高いパフォーマンスが必要な場合に問題があります。

于 2008-10-23T12:42:18.267 に答える
0

「ストアド プロシージャは CRUD/ビジネス ロジックの使用には適していません」というキャンプにしっかりと足を踏み入れてください。レポート、データのインポートなどの必要性を理解しています

ここに書き込んで...

于 2009-06-08T18:49:02.773 に答える
-1

Microsoft SQL Server の場合、実行計画のキャッシュと再利用を支援するために、可能な限りストアド プロシージャを使用する必要があります。プランの再利用を最適化する理由は何ですか? 実行計画の生成にはかなりのコストがかかるためです。

アドホック クエリの実行プランのキャッシュと再利用は、SQL サーバーの新しいエディション (特に 2005 と 2008) で大幅に改善されましたが、アドホック クエリよりもストアド プロシージャを処理する場合のプランの再利用に関する問題はまだはるかに少なくなっています。 . たとえば、SQL サーバーは、計画のテキストが正確に一致する場合にのみ実行計画を再利用します。たとえば、次の SQL 行がそれぞれ独立して実行される場合、それらのどれも使用しません。同じ実行計画:

SELECT MyColumn FROM MyTable WHERE id = @id
select MyColumn from MyTable WHERE id = @id
SELECT MyColumn  FROM MyTable WHERE id = @id
SELECT MyColumn FROM MyTable WHERE id = @id -- "some comment"
SELECT MyColumn FROM MyTable WHERE id = @id -- "some other comment"

これに加えて、パラメーターの型を明示的に指定しないと、SQL Server が間違って取得する可能性が高くなります。たとえば、上記のクエリを入力 4 で実行した場合、SQL Server は@id を SMALLINT (または場合によっては TINYINT) としてクエリを実行するため、たとえば 4000 の @id を使用して同じクエリを実行すると、SQL Server はそれを INT としてパラメータ化し、同じキャッシュを再利用しません。

他にもいくつかの問題があると思います。正直なところ、それらのほとんどはおそらく回避できます。特に SQL Server の新しいエディションでは問題ありませんが、一般的にストアド プロシージャを使用すると、より多くの制御が可能になります。

于 2009-06-08T19:38:31.753 に答える