2011-07-28 19 views
0

カーソルを最初に試してみましょう。簡単に取りましょう= Pカーソルは、すべて傘下のグループの下にある会社IDのリストを取得することになっています。その後、特定の会社をターゲットにして、そのワークフロー記録をカーソル内の会社にコピーします。カーソルが無限ループに詰まっています

これらのワークフローレコードをすべての企業に無限に挿入します...ここで問題は何ですか?

ここでn00bの間違いはありますか?

DECLARE @GroupId int = 36; 
DECLARE @CompanyToCopy int = 190 
DECLARE @NextId int; 
Declare @Companies CURSOR; 

SET @Companies = CURSOR FOR 
SELECT CompanyId 
FROM Company C 
    INNER JOIN [Group] G 
     ON C.GroupID = G.GroupID 
WHERE C.CompanyID != 190 
     AND 
     G.GroupId = @GroupId 
     AND 
     C.CompanyID != 0 

OPEN @Companies 
FETCH NEXT 
FROM @Companies INTO @NextId 

WHILE (@@FETCH_STATUS = 0) 
BEGIN 

    INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name) 
    (SELECT 
      @NextId, 
      W.EndOfWorkflowAction, 
      W.LetterType, 
      W.Name 
    FROM COI.Workflow W) 

    FETCH NEXT 
    FROM @Companies INTO @NextId 
END 
CLOSE @Companies; 
DEALLOCATE @Companies; 

編集:

私はそれを行うように言われた後...私は実際にはかなりのようにそれを行う方法のような答えを持っていないことに気付きましたからといっ基づいて、このセットを作る試みことにしましたセットベースのクエリ。

ありがとうございました。私は後世のためのセットベースのバージョンを投稿します。

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name) 
(
SELECT 
    CG.CompanyId, 
    W.EndOfWorkflowAction, 
    W.LetterType, 
    W.Name 
FROM COI.Workflow W 
    CROSS JOIN (SELECT C.CompanyID 
       FROM Company C 
        INNER JOIN [Group] G 
         ON G.GroupID = C.GroupID 
       WHERE C.CompanyID != 190 
         AND 
         C.CompanyID != 0 
         AND 
         G.GroupID = 36 
       ) AS CG 
WHERE W.CompanyID = 190 
) 
+6

カーソルを使用する必要はありません。可能な限り避けてください。 –

+3

@Mitchが正しいです。特別なものを除いてすべてのものにカーソルを使用しないでください。彼らは遅く、多量のリソースを消費し、すぐにデッドロックにつながる可能性があります。 –

+0

Tyさんにアドバイスをお願いします。しかし、これは私がそれらを学ぶための口実として使用している単なる工夫された問題です。それを念頭に置いて、問題は何ですか? –

答えて

3

この上の条件WHEREあなたはありません持っている:

SELECT 
      @NextId, 
      W.EndOfWorkflowAction, 
      W.LetterType, 
      W.Name 
    FROM COI.Workflow W 
    -- WHERE CompanyID = @CompanyToCopy -- This should be here 

ですから、効果倍増の種類を取得しています。

initial state, company 190, seed row (0) 

pass one, company 2, copy of seed row (1) 
now 2 rows 

pass two, company 3, copy of seed row (0) - call this (2) 
pass two, company 3, copy of copy of seed row (1) - call this (3) 
now 4 rows 

then 8 rows, etc 
2

あなたのロジックは間違っています(カーソルを使用しているために幾分隠されています!)。

あなたの投稿コードはCOI.Workflowの各行に対して、最初の選択条件に一致する会社の数を掛けてCOI.Workflowに行を挿入しようとしています。 (挿入物のSELECTステートメントに条件がないことに注意してください:あなたはテーブル全体を選択しています)。ループを通過するたびに、行の数が2倍になりますCOI.Workflow

したがって、無限ではありませんが、非常に長くなる可能性があります。

私はあなたがセットベースのステートメントとして書き直すことをお勧めします、そして、ロジックはより明確になります。

2

すべてのワークフローレコードの新しいコピーを各繰り返しごとにワークフローテーブルに挿入するので、毎回サイズが倍になります。たとえば、カーソルに30個の項目がある場合は、以前よりも1073741824倍多くのレコードを含むワークフローテーブルが作成されます。

0

カーソルの最初の使用はOKです。INSERT ... SELECTロジックのすべての問題です。 COI.Workflowテーブルに何を挿入する必要があるのか​​分かりません。 私は、あなたの現在のWHERE条件がレコードを2倍にするという以前のコメントの意見に同意しますが、毎回各会社のフル・ダブルレコードを挿入したいとは思いません。 ので、私たちはレコードを挿入するあなたのロジックについての詳細を知っている必要があり、あなたが

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name) 
(SELECT TOP 1 
     @NextId, 
     W.EndOfWorkflowAction, 
     W.LetterType, 
     W.Name 
FROM COI.Workflow W) 

ようなものが必要だと思いますか。

関連する問題