2011-07-28 5 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

타이를위한 조언. 그러나 이것은 내가 그들을 배울 핑계로 사용하고있는 고의적 인 문제 일뿐입니다. 이를 염두에두고 문제가 무엇입니까? –

답변

3

당신이없는 곳에서 조건 :

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 문에 조건이 없는데 전체 테이블을 선택하는 방법에 유의하십시오. 루프를 통과 할 때마다 행 수가 두 배로 늘어납니다. COI.Workflow

그래서 무한하지 않지만 매우 길 수도 있습니다.

당신이 세트 기반 진술로 다시 작성하고 논리가 명확하게 될 것이 좋습니다.

2

워크 플로 테이블에 모든 워크 플로 레코드의 새 복사본을 각 반복마다 삽입하므로 매번 크기가 두 배가됩니다. 예를 들어 커서에 30 개의 항목이있는 경우 이전보다 1073741824 배 많은 레코드가있는 워크 플로 테이블로 끝납니다.

0

첫 번째 커서 사용은 INSERT ... SELECT 논리의 모든 문제는 정상입니다. COI.Workflow 테이블에 무엇을 삽입해야하는지 이해할 수 없습니다. 나는 현재 WHERE 조건이 레코드를 두 배로 늘린 이전 commentatorts에 동의하지만 매번 각 회사에 대해 full-doubled 레코드를 삽입한다고 생각하지 않습니다. 그래서, 나는 우리가 레코드를 삽입하는 논리에 대한 자세한 내용을 알고 있어야합니다, 당신은

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

뭔가를해야한다고 생각 또는.

관련 문제