2009-07-31 11 views
4

私は長いストアドプロシージャを管理しやすくしようとしていますが、例えば、テーブルにデータを挿入し、タイプの挿入に応じてsprocを作成したいなど、ストアドプロシージャを呼び出すストアドプロシージャを持つのは間違っていますか?そのタイプのテーブルへの追加情報:他のストアドプロシージャを呼び出すストアドプロシージャが不正ですか?

BEGIN TRANSACTION 

     INSERT INTO dbo.ITSUsage (
      Customer_ID, 
      [Type], 
      Source 
     ) VALUES ( 
      @Customer_ID, 
      @Type, 
      @Source 
      ) 
    SET @ID = SCOPE_IDENTITY() 

    IF @Type = 1 
     BEGIN 
        exec usp_Type1_INS @ID, @UsageInfo 
      END 
     IF @TYPE = 2 
       BEGIN 
        exec usp_Type2_INS @ID, @UsageInfo 
      END 

    IF (@@ERROR <> 0) 
     ROLLBACK TRANSACTION 
    ELSE 
     COMMIT TRANSACTION  

これは私のアプリケーションで処理する必要がありますか?

+1

あなたは@@ ERRORを捨てそしてTRY(しようとキャッチ)とXACT_STATE() –

+0

これは2K5以降... – Joe

答えて

12

私たちは常に他のprocsからprocsを呼び出します。それ以外の場合、データベース集約型(またはデータベースのみ)のアプリケーションを分割するのは難しい/不可能です。

+2

が合意されていると仮定します。BEGIN使用しますが、行うかが必要になる場合がありますコールチェーンのprocsのに注意することがあります親procがロールバックする可能性がある場合はコミットを行います。 –

+0

はい。基本的には単一のサンドボックスに入っているので、他のprocsが共有環境に何をするのか心配する必要があります。 – Joe

+0

INSERT EXECステートメントはネストできないことにも注意してください。つまり、他のプロシージャを呼び出して返されるレコードセットを一時テーブルに格納するプロシージャです。 – jandersson

4

いいえ、それは完全に受け入れられます。

3

同じDBスキーマ内にある限り、私の意見では完全に受け入れられます。複製に常に有利な再利用です。それは、アプリケーション層内のメソッドを呼び出すようなものです。

3

すべてではない、私も別のプロシージャ内からプロシージャを呼び出す

+0

それは私がそれをしたいと思っている理由です。 –

9

が完全に受け入れているあなたのコード内のメソッドを作成するのと同じ理由のためにお勧めします、と言うでしょう。

ただし、@@ ERRORに依存するTransact-SQLでは、エラーが発生しやすくなります。ケースインポイント、あなたのコード。挿入エラー、および呼び出されたプロシージャ内で生成されたエラーを検出することはできません。 @@ ERRORは実行された各文がリセットされ、最後の文の結果のみが保持されるためです。私はcorrect template of error handling in Transact-SQLとトランザクションネストを示すブログエントリを持っています。また、Erland Sommarskogには、長いこと今、reference read on error handling in Transact-SQLという記事があります。

4

間違いなく、

私は、小さな、単一目的のものにリファクタリングされて本当に恩恵を受けたはずの20種類の異なるストアドプロシージャを見てきました。

2

No.再利用を促進し、機能をコンポーネント化することができます。

3

別のストアドプロシージャを呼び出す1つのストアドプロシージャは正常です。あなたが行くことができるまでネスティングのレベルには限界があります。

SQL Serverでは、現在の入れ子レベルが@@NESTLEVEL関数によって返されます。

ここストアドプロシージャのネストセクションhttp://msdn.microsoft.com/en-us/library/aa258259(SQL.80).aspx

歓声我々はストアドプロシージャとトリガ(適用)の両方に共通のコードを統合するストアドプロシージャを使用して、当社のIT領域で

1

を確認してください。また、SQLソースの重複を避けるためには、事実上必須です。

1

この質問に対する一般的な答えは、もちろん、いいえ - それはSQLストアドプロシージャをコーディングする通常の、さらに好ましい方法です。

しかし、あなたの特定のケースではそれはあまり良い考えではないかもしれません。

アプリケーション(Java、.Netなど)でデータアクセス層(DAO)をサポートする一連のストアドプロシージャを維持する場合)、そしてデータベース層(ストアドプロシージャをそのように呼び出す)を効率化し、比較的薄くすることは、全体的な設計に利益をもたらすでしょう。従って、ストアド・プロシージャ・コールの広範なグラフを有することは、実際に、そのようなアプリケーションにおける全体的なデータ・アクセス・ロジックを維持し、サポートするには悪い可能性がある。

私はDAOとデータベース層の間のロジックのより均一な分布に傾き、ストアドプロシージャコードが単一の関数呼び出しの中に収まるようにします。

2

他の人が指摘しているように、これは機能の重複を避けるために完全に受け入れられ、必要です。

しかし、ネストされたストアドプロシージャコールのトランザクションの監視は、rollback transactionを発行する前に@@TRANCOUNTをチェックする必要があります。ネストされたすべてのトランザクションをロールバックするためです。詳細な説明はarticleにチェックしてください。

+0

+1記事のリンクです。ありがとう! – Dubs

1

はいそれは悪いです。 SQL Serverは、1つのストアドプロシージャをサポートし、別のストアドプロシージャを呼び出すことを許可します。可能であれば、私はこの設計を避けるように全般的に努力します。私の理由?他のポスターの正しいコメントに追加

single responsibility principle

+0

実際に*他のストアドプロシージャを呼び出す*コードはどうでしょうか?この原則に違反していないか? – ajh1138

0

、何も悪いことは、原則的にありませんが、手順がどの外部アプリケーションによってインスタンスに対して呼び出されている場合には、あなたは実行時間に注意する必要があります特定のタイムアウトに準拠しています。

Webアプリケーションからストアドプロシージャを呼び出す場合の典型的な例:ストアドプロシージャが正しくコミットされている場合でも、Webアプリケーションでエラーが発生するまでに長い時間がかかると、デフォルトのタイムアウトが発生します。 外部サービスから電話をかけても同じことが起こります。 これは、アプリケーションでの動作が一貫しないため、外部サービスなどでエラー管理ルーチンがトリガされる可能性があります。

このような状況にある場合は、長時間実行された子コールを別のプロセスにリダイレクトするService Brokerを使用します。

関連する問題