web-dev-qa-db-ja.com

処理中に入力を求めるストアドプロシージャ

したがって、これがSQL内でも可能かどうかを確認するように求めています。

現在、データベース内のデータを操作するために使用しているVB.Netアプリケーションのいくつかのストアドプロシージャを作成しています。

一連のレコードを削除するプロシージャを作成していますが、プロシージャ自体がアイテムを削除するかどうかの確認を求めることができるかどうかを知りたいです。メッセージプロンプトのようなもの、またはプロシージャが次の入力を待つために一時停止するようなもの。

これが実行できない場合は、VB.Net側でそれを管理する方法を知っています。データベース自体にSQLとデータベースの要素をできるだけ多く保持しようとしています。

4
Skitzafreak

簡単に言えば、ストアドプロシージャは、実行後に入力を受け入れてトランザクションで利用するように求めるプロンプトを表示することはできません。

実行できることは、ストアドプロシージャを使用して、検証する数または値を取得することです。これに基づいて、コードでロジック関数を使用して、アクションを実行する2番目のストアドプロシージャを呼び出すことができます。

同様に、このIF ELSEロジックをプロシージャに組み込むことができます。値が1のテーブルからすべてのレコードを削除するとします。50回の削除が予想されます。ストアドプロシージャを呼び出して値50を入力すると、次のように実行されます。

SELECT COUNT(*) FROM TABLE WHERE Value = 1 

検証を行って、カウントが50以上、50以下であることを確認し、別のプロシージャを呼び出して別のパラメータを削除プロシージャとして渡すか、アクションを終了することができます。

私は通常、ストアドプロシージャをデイジーチェーンで接続することに反対しており、アプリケーションでビジネスロジックを保持したいので、VBで処理することをお勧めします。

9
Shaulinator

もっとも近いのは、ストアドプロシージャがトランザクションを必要とする場合です。例えば

if @@trancount = 0 throw 50001, 'A transaction is required to run this procedure', 10

次に、アプリケーションは、ストアドプロシージャの実行後に変更を明示的にコミットする必要があります。

これを処理するには、いくつかの「標準」の方法があります。

  1. _@Force_パラメータを追加します。プロシージャが初めて実行されたときにRAISERRORを実行し、メッセージボックスをユーザーに表示します。ユーザーが同意した場合は、_@Force_パラメータを設定してプロシージャを再度呼び出します。 TOCTOUの問題により失われた変更の確認が問題である場合は、_@Force_パラメータを承認されたレコードのリストにします。
  2. プロシージャを小さな部分に分割して、アプリケーションが中間状態に公開されるようにします。 (BuildChangeSet、次にIF EXISTS(SELECT 1 FROM #ChangesPending)→メッセージボックス、次にExecuteChanges
  3. ORMを使用してC#/ VBにプロシージャを実装し、「実際の」ストアドプロシージャを回避しながら、SQLのようなテーブルへのアクセスを容易にします。
  4. アプリに消えない変更を回避させ、確認よりも明らかに「元に戻す」ボタンを優先させる

(技術的には可能ですが)DBAが最終的にあなたの終焉を望んでしまうような解決策もいくつかあります。

  1. トランザクションを開き、更新を行い、結果セットまたは非終了エラーを介して警告を返し、ユーザーが同意を与えるか、トランザクションのロールバックを要求するまで、トランザクションをコミットしないで保持します。 (ロックは、ユーザーが応答するまで数分間保持される場合があります)
  2. 通信メカニズムを使用して、待機中にsprocからコールバックします。 (Service Brokerはこれを許可します。CLRがUnsafe、COM相互運用機能、外部スクリプトで実行された場合と同様に、他のいくつかの方法で確信しています)

これを解決したとしても、データアクセスにUIが混在しているため、単一層アプリに制限されます。


TL; DR:はい、ストアドプロシージャからの外部イベントで待機することは可能ですが、待機しないでください。これはSQL Serverの目的ではありません。

1
Mitch