1

私は現在、レガシーアプリケーションに取り組んでおり、怪しげな SQL を継承しています。このプロジェクトはまだ生産されていませんが、現在進行中です。最初のテスト中に、バグが見つかりました。アプリケーションは、他の多くのストアド プロシージャを呼び出すストアド プロシージャを呼び出し、カーソルを作成し、カーソルをループ処理し、その他多くのことを行います。FML。

現在のアプリの設計方法では、ストアド プロシージャを呼び出してから、新しいデータ セットで UI を再読み込みします。もちろん、表示したいデータはまだ SQL サーバー側で処理されているため、UI の結果は表示された時点では完全ではありません。これを修正するために、UI をロードする前にスレッドを 30 秒間スリープさせました。これはひどいハックであり、SQL 側でこれを適切に修正したいと考えています。

私の質問は...分岐ストアド プロシージャを関数に変換する価値はありますか? これにより、メインラインのストアド プロシージャは、処理を行う前に戻り値を待機するようになりますか?

ストアド プロシージャは次のとおりです。

    ALTER PROCEDURE [dbo].[ALLOCATE_BUDGET] 
    @budget_scenario_id uniqueidentifier
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @constraint_type varchar(25)

    -- get project cache id and constraint type
    SELECT @constraint_type = CONSTRAINT_TYPE
    FROM BUDGET_SCENARIO WHERE BUDGET_SCENARIO_ID = @budget_scenario_id

    -- constraint type is Region by Region
    IF (@constraint_type = 'Region by Region')
      EXEC BUDGET_ALLOCATE_SCENARIO_REGIONBYREGION @budget_scenario_id

    -- constraint type is City Wide
    IF (@constraint_type = 'City Wide')
      EXEC BUDGET_ALLOCATE_SCENARIO_CITYWIDE @budget_scenario_id

    -- constraint type is Do Nothing
    IF (@constraint_type = 'Do Nothing')
      EXEC BUDGET_ALLOCATE_SCENARIO_DONOTHING @budget_scenario_id

    -- constraint type is Unconstrained
    IF (@constraint_type = 'Unconstrained')
      EXEC BUDGET_ALLOCATE_SCENARIO_UNCONSTRAINED @budget_scenario_id

    --set budget scenario status to "Allocated", so reporting tabs in the application are populated
    EXEC BUDGET_UPDATE_SCENARIO_STATUS @budget_scenario_id, 'Allocated'
END

呼び出し元の .NET アプリケーション UI に不完全な結果セットが表示されないようにするために、分岐呼び出しのカーソルが完了する前に、これらのストアド プロシージャを戻り値を持つ関数に変換する価値はありますか? これにより、[ALLOCATED_BUDGET] ストアド プロシージャへのメイン コールが完了する前に SQL が待機することになりますか?

  • ストアド プロシージャ内の最後の SQL ステートメント呼び出しにより、ステータスが "割り当て済み" に設定されます。これは、前の呼び出しのカーソルの処理が完了する前に発生しています。これらの呼び出しを関数呼び出しにすると、ストアド プロシージャがアプリケーションにフォーカスを返す方法に影響しますか?

フィードバックは大歓迎です。SQL 関数を使用することは正しいと思いますが、100% 確実ではありません。

** 追加情報:

  1. コードを実行すると、接続文字列で [async=true] が使用されます
  2. コードの実行は [SqlCommand].[ExecuteNonQuery] メソッドを使用します
4

6 に答える 6

2

バックグラウンドで実行しているときに、ストアドプロシージャが呼び出し元に戻る可能性があるとは聞いたことがありません。

実際、私はそれが起こっているとは思わないと言うところまで行きます。UIと、SPが実行すべきであると信じていることとの間に違いが見られる場合は、別の原因があると思います。

接続文字列にはasync=trueが含まれていますか?SPはBeginExecuteReaderまたはBegin-他のものを使用して実行されていますか?

于 2009-07-20T17:35:30.410 に答える
2

子ストアド プロシージャでRETURN ステートメントを使用することもできます。これを使用して、親プロシージャに結果コードを返すことができます。" "の行に沿って子プロシージャを呼び出すことができますexec @myresultcode = BUDGET_ALLOCATE_SCENARIO_REGIONBYREGION()。これにより、親プロシージャは子プロシージャが終了するまで待機する必要があると思います。

于 2009-07-20T17:22:02.263 に答える
2

どのようにプロシージャを呼び出していますか? ExecuteNonQuery() を使用してプロシージャを呼び出していると思います。ExecuteScalar() を使用してプロシージャを呼び出してみて、次のようにプロシージャを変更します。

ALTER PROCEDURE [dbo].[ALLOCATE_BUDGET] 
    @budget_scenario_id uniqueidentifier
AS
BEGIN
   ...

    RETURN True
END

これにより、.NET のデータ実行コードは、手順が完了するまで待機してから続行する必要があります。プロシージャの実行中に UI を「ハング」させたくない場合は、BackgroundWorkerProcess などを使用して別のスレッドでクエリを実行し、完了したコールバックを探して結果で UI を更新します。

于 2009-07-20T17:24:38.560 に答える
0

単純に聞こえるかもしれませんが、ストアド プロシージャのステータスを格納できるテーブルを作成することをお勧めします。どういうわけか、プロセス全体とサブプロセスの実行が終了したことを示すことができるフラグ。

UI からこれをクエリして、このステータス コードをポーリングすることで処理が完了したかどうかを確認できます。

于 2009-07-20T17:16:43.083 に答える
0

個人的には、これを関数に変換するよりも、これらのカーソルを置き換えることにはるかに関心があります。

そして、前の proc からの有効な戻りコードをチェックするまで、最後の proc を実行しません (前の proc の 1 つが停止すると、これは本当に問題になります!)

また、これがすべてトランザクション内にある必要があるかどうかも検討してください (これらのプロシージャはテーブル内のデータを変更していますか?)

(Do Nothing のプロセスを実行する proc があるのがおかしいと思うのは私だけですか?)

于 2009-07-20T18:50:54.487 に答える
0

これらの呼び出しを関数呼び出しにすると、ストアド プロシージャがアプリケーションにフォーカスを返す方法に影響しますか?

いいえ。

ストアド プロシージャは、その呼び出し元が UI アプリケーションであることを認識していません。ストアド プロシージャには、UI アプリケーションの動作に影響を与える可能性のあるものは何もありません。

ほとんどの場合、UI アプリケーションは 1 つの接続でストアド プロシージャを呼び出し、別の接続でそのデータを更新しています。UI の更新を遅らせる方法はたくさんありますが、私がプッシュする方法の 1 つは、データベース接続を 1 つにすることです。

于 2009-07-20T17:24:00.573 に答える