web-dev-qa-db-ja.com

ストアドプロシージャ(つまり、すべてのビジネスロジック)をクライアントデータベースから分離して、クライアントデータのみが含まれるようにするにはどうすればよいですか?

シナリオ:アプリケーションデータベース(SQL Server 2012)には、ストアドプロシージャ(SP)のビジネスロジック全体が含まれています。 DBをクライアントに公開する必要があるたびに、不必要にSPがクライアントDBにコピーされます。

問題:すべてのビジネスロジックがクライアント側でコピーされ、独自の問題が発生します。

以前に試したソリューション

  1. 暗号化を使用した手順Proc_Nameの作成

    この方法では、暗号化されて保守不可能なSPコードになります。クライアント側で実行されているコードのバージョンを判断できないため、デバッグできません。バージョン管理を適用できません。さらに、クライアントは実行できません。暗号化されたSPは複製されないため、DB複製。

  2. LinkedServerDB.SchemaName.Proc_NameのシノニムSchemaName.Proc_Nameを作成します

    これにより、Remote_Linked_Server_DBにある実際のSPにアクセスする参照(シノニム)をClient_DBに作成できます。各SP呼び出しでは、データ全体がClient_DBからアクセスされ、Remote_Linked_Server_DBに送信され、そこで計算が行われ、結果が返送されます。これにより、パフォーマンスに深刻な問題が発生します。また、リモートリンクサーバー。

要件(編集済み)

  1. ストアドプロシージャコードをコンパイル(保護)して、クライアントデータベースから分離できるソリューションを探しています。
  2. コンパイルされたストアドプロシージャコードは、SYNONYMSを使用する場合のように、クライアントがストアドプロシージャにアクセスするためにリモートの場所に24時間365日接続する必要がないように、クライアント側で使用できる必要があります。
  3. Visual StudioデータベースプロジェクトでCLR-SQLを使用することについて少しヒントがありますが、すべてのストアドプロシージャを書き直す必要があると思います(100を超えるSPがあるため、これはほぼ不可能です)。
2
Ish Goel

記載されている要件に反映されていない、以前の試行が機能しなかった理由があるため、要件が完全であるとは思いません。試行されたソリューション#1で、コードをデバッグできる必要がある/コードがどのバージョンであるかを知っている必要があり、クライアントがコードを複製できる必要があると述べました。これらの2つの問題は現在の要件ですか?

それでもレプリケーションの必要性が必要な場合は、「コンパイル(保護)」するという要件と矛盾します。

クライアントのサーバーは、saに完全にアクセスできるものであるため、VIEW ANY DEFINITION権限を拒否することは実行可能なアプローチではないと想定します。

試してみる1つのことは、ストアドプロシージャのT-SQLを取得し、それぞれを変更せずにCLRストアドプロシージャにカプセル化することです。 1つ以上の関連するストアドプロシージャをアセンブリに配置します。これについてのいくつかの考えは次のとおりです。

  • アセンブリには、 sys.assemblies カタログビュー、SSMS(アセンブリを右クリックしてプロパティを表示)、および [〜#〜])に表示されるバージョン番号があります。 assemblyproperty [〜#〜] 関数。
  • おそらく、すべてのストアドプロシージャを単一のアセンブリに入れたくないでしょうが、ストアドプロシージャごとに1つのアセンブリを持ちたくない場合もあります。ストアドプロシージャごとに1つのクラスファイルを作成し、それらのいくつかを1つのアセンブリに含めることができます。
  • すべてのアセンブリはWITH PERMISSION_SET = SAFEを使用する必要があります
  • 各CLRストアドプロシージャの唯一のコードは次のとおりです。
    • CommandTypeがCommandType.TextでCommandTextが現在のT-SQLストアドプロシージャのコンテンツに設定された SqlCommand を作成します
    • SqlConnectionは必要ありません(必要な場合は、"context connection=true"です)
    • SqlCommandのSqlParameterCollectionをCLRストアドプロシージャの入力パラメーターにマップします
    • 呼び出し SqlContext.Pipe.ExecuteAndSend(_YourSqlCommand);
  • アセンブリおよび関連するストアドプロシージャは、各クライアントDBにロードされます
  • CLRストアドプロシージャは複製できませんが、おそらく回避できる可能性があります
2
Solomon Rutzky

システムをSQL2014にアップグレードできる場合は、 ここ を参照して、ネイティブにコンパイルされたストアドプロシージャについて読んでください。これにより、コードが保護され、パフォーマンスが向上する可能性があります。

おそらく少し遅れますが、ビジネスロジックは可能な場合はアプリケーション層で実行する必要があります。これにより、すべてのロジックが1か所に保持され、Microsoft SQLServerを使用する場合に非常にコストがかかる可能性があるデータベースレベルでのCPUリソースの必要性が減少します。

0
James Anderson

データベースを顧客に渡す必要がある場合は常に、最初に最新のコピーをステージングDBとして復元します。そのステージングDBに対してこれを実行します。

select 'drop procedure ' + name + ';' from sys.objects where type = 'P';

SPが複数のスキーマに分散している場合は、sys.schemasも関与する必要があります。上記の出力を取得し、ステージングDBに対して実行します。関数、トリガー、その他の実行可能ファイル、および任意のタイプのオブジェクトに対して同様のことを行うことができます。完了したら、ステージングDBをバックアップし、それをお客様に送信します。すべてを自動化できます。

0
Michael Green