2009-07-20 25 views
1

現在、私は従来のアプリケーションで作業しており、それを使っていくつかの陰的なSQLを継承しています。このプロジェクトは決して生産に入ったことはありませんが、今のところそれが実現しています。初期テスト中にバグが見つかりました。アプリケーションは、多くの他のストアドプロシージャを呼び出し、カーソル、カーソルを使用してループを作成するストアドプロシージャなどを呼び出します。 FML。SQLユーザー定義関数とストアドプロシージャの分岐の比較

現在、アプリケーションの設計方法では、ストアドプロシージャを呼び出してから、新しいUIで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で不完全な結果セットを表示しないようにするには、分岐の呼び出しでカーソルが完了する前に、それはにこれらのストアドプロシージャを変換するworthwileです戻り値を持つ関数?これは、[ALLOCATED_BUDGET]ストアドプロシージャへのメインコールを完了する前にSQLを待機させるでしょうか?

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

ご意見をいただければ幸いです。私はSQL関数に向いているが、100%確実ではないと感じている。

**追加情報:。

  1. 接続文字列の[非同期=真]コード用途を実行するコードを実行
  2. は、[SqlCommandオブジェクト] [は、ExecuteNonQuery]方法

答えて

2

どのように手続きを呼び出していますか?プロシージャを呼び出すためにExecuteNonQuery()を使用していると推測します。 ExecuteScalarを(使用してプロシージャを呼び出して試してみてください)、以下のような手順を変更します。

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

    RETURN True 
END 

これは、続行する前に完了するの手続きを待つために、.NETでデータの実行コードが発生する必要があります。プロシージャの実行中にUIが「ハング」しないようにするには、BackgroundWorkerProcessまたは同様のものを使用して別のスレッドでクエリを実行し、完了したコールバックを検索してUIを更新します。

+0

実行コードが[SqlCommand]。[ExecuteNonQuery]メソッドを使用します – D3vtr0n

0

を使用しますシンプルに聞こえる危険性があるので、私はあなたが格納されているprocの状態を格納することができるテーブルを作成することをお勧めします。何らかの形で、プロセス全体が&サブプロセスが実行を終了したことを示すことができるフラグ。

これをUIから照会して、このステータスコードをポーリングすることで何かが行われているかどうかを確認できます。

+0

メーリングリストのあまりのように聞こえることデータアクセスは、私の好みのために進行中です。 – D3vtr0n

2

子ストアドプロシージャでRETURN statementを使用することもできます。これを使用して、結果コードを親プロシージャに戻すことができます。 "exec @myresultcode = BUDGET_ALLOCATE_SCENARIO_REGIONBYREGION()"の行に沿って何かで子プロセスを呼び出すことができます。私は、親プロシージャが子プロシージャが終了するのを待たせるべきだと思う。

+0

それは関数ではなくストアドプロシージャであれば違いはありませんか?定義による関数戻り値。それらを機能させることは安全ではありませんか?戻り値を確認して、成功したことを確認してから、scenario_statusを更新します。ご協力ありがとうございました。 – D3vtr0n

+1

関数やストアドプロシージャを作成するかどうかはあなた次第です。関数には、ストアドプロシージャと比較して何ができるのかにはより多くの制限があることに注意してください。たとえば、ストアドプロシージャ内に更新ステートメントを入れることはできません。詳細は、この記事(http://msdn.microsoft.com/en-us/library/ms187650.aspx)を参照してください。ストアドプロシージャとして保持する方が簡単かもしれません。 – tbreffni

+0

良い点。それを指摘していただきありがとうございます。 – D3vtr0n

0

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

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

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

+0

私は同意する、私は単一のデータベース接続(シングルトン)でアプリケーションを書くことを好む。問題は、私はこのコードを書いていないということです。このコードは4年以上の間に構築され、その後棚上げされました。今は悪いホラー映画のように戻ってきました。関数を使用する私の考えは、関数が定義によって値を返すことです。上記のストアドプロシージャは、そのファンクション値が返されるまで、ブランチまたはそれ以上の処理(上記のストアドプロシージャの最後のEXECステートメントなど)を許可しません。または私は間違っていますか? – D3vtr0n

+1

BEGIN TRANSACTION? –

2

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

実際、私はそれが起こっているとは思わないと言います。あなたがUIとあなたがSPがやったと信じていることの違いが見えているなら、それは別の原因があると信じています。

接続文字列にasync = trueが含まれていますか? BeginExecuteReaderまたはBegin何かを使ってSPを実行していますか?

+0

接続文字列に[async = true]を追加しましたが、同じ問題の結果が表示されます。 SQLコマンドオブジェクトとExecuteNonQueryメソッドを使用して実行されます。 – D3vtr0n

+1

私はそれが助けると思ったので、async = trueは言及しなかった。 Begin *メソッドを呼び出さない場合、効果はありません。あなたの問題は、SPが返品後も引き続き実行しているとはまだ信じられません。他に何かが起こっている。 –

+0

それは明らかに子プロセスのカーソルです。 UIが更新されている間、バックグラウンドプロセスのように実行されています。私が必要とするのは、私のSQLリターンの流れをより良くコントロールすることです。このことは混乱ですが、チャレンジのためです。あなたのご意見ありがとうございます。 – D3vtr0n

0

個人的には、これを関数に変換するよりも、カーソルを置き換える方がずっと心配です。

そして私は、以前のprocsのからの有効な戻りコードをチェックするまでの最後のPROCを実行しません(前のprocsのの1が死亡した場合は、この事が本当の困っている!)、これはすべてするかどう

も考慮トランザクションで(テーブル内のデータを変更するこれらのprocsのは?)

(Iあなたが何もしないための処理を実行するためのPROCを持っている面白いことを見つけただけで一人?)

+0

カーソルの代わりに何をお勧めしますか?私は同意する、私はその最後のEXECステートメントをそこから、アプリケーションからの独自の呼び出しに移動します。私はトランザクションもこれを包み込むという考えが好きです。 – D3vtr0n

+0

私は彼らが何をしているか知るまでカーソルの代わりに何もお勧めできませんセットベースのステートメントでカーソルを置き換える方法は、カーソルがやっている作業に非常に依存しています。そして、すべてのカーソルを置き換えることはできませんが、おそらく90%以上が可能です。 – HLGEM

関連する問題