2015-02-04 2 views
0

while 루프를 사용하는 저장 프로 시저가 있습니다. 모든 기록을 읽고 그 결과를 알려줘야합니다. 6 개의 레코드가 반환되었지만 6 번째 레코드의 결과가 6 번 인쇄됩니다.SQL Server 2008 : WHILE 루프가 모든 행을 반복하지 않습니다.

DECLARE @num_month float, @RowCount int, @Init int 

--Get count of SubrowID 
SET @RowCount = (SELECT COUNT(SubrowID) 
       FROM tblSubrow 
       WHERE SubrowID = 13) 

SET @Init = 1 

--Iterate each SubrowID 
WHILE (@Init <= @RowCount) 
BEGIN 
    SELECT 
     @num_month = SUBSTRING(CAST(DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float)/CAST(30 AS float)/CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float)/CAST(30 AS float)/CAST(10 AS float), 1)), 2) 
    FROM 
     tblSubrow 
    WHERE 
     SubrowID = '13' 

    print @num_month 

    SET @Init = @Init + 1 
END 
+6

루프 카운터를 쿼리의 어딘가에서 사용한 경우 매번 다른 값이 반환됩니다. 흔히 똑같은 쿼리를 반복해서 실행하면 같은 결과를 얻습니다. while 루프에서도 커서와 간단한 'while'루프가 혼동을 일으킬 수 있습니다. 정말로 이러한 유형의 처리를 원한다면 커서를 사용하는 법을 배워야합니다. –

+4

여기서 루프를하려고합니다. 어떻게 각 행을 식별 할 것인가? –

+0

커서는 사용하지 않는 것이 좋습니다라고 했으므로 while 루프를 사용하려고합니다. tblSubrow 테이블에서 6 startdate와 enddate를 루프해야합니다. 그들은 모두 시작일과 종료일이 다릅니다. – angelcake

답변

0

WHILE 루프 선택은 항상 6 개의 행을 반환하며 @num_month 변수는 마지막 결과 행, 즉이 경우 6 번째 행으로 설정됩니다.

귀하의 요구 사항과 왜 WHILE 루프에 넣어야하는지 잘 모르겠습니다.

는 [tblSubrow,

  1. [tblSubrowRowid] 아래의 테이블의 기본 키 가정 대신 테이블 변수를 채우는 결과 집합을 사용

    .

  2. s.StartDate 및 s.EndDate는 [tblSubrow]의 열입니다. ([tblSubrow]의 별칭은 아닙니다.)
  3. num_month에 대한 계산은 사용자가 요구 한 것이 아니기 때문에 요구 사항에 의해 결정됩니다.

    DECLARE @updateTable AS TABLE ([rowid] INT, [num_month] FLOAT); 
    INSERT INTO @updateTable 
        ([rowid], [num_month]) 
    SELECT 
        [tblSubrowRowid], SUBSTRING(CAST(DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float)/CAST(30 AS float)/CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float)/CAST(30 AS float)/CAST(10 AS float), 1)), 2) 
    FROM 
        [tblSubrow] 
    WHERE 
        SubrowID = '13'; 
    

그런 다음 필요에 따라 [tblSubrow] 또는 다른 테이블 업데이트 할 @updateTable의 데이터를 사용할 수 있습니다.

SQL은 항상 설정 기반이므로이 방법을 사용하는 것이 가장 좋습니다.

+0

전체 저장소 프로 시저의 각 행에 대해 실제로 이후에 일부 업데이트가 있고 업데이트를 수행하기 위해 모든 레코드를 반복해야합니다. – angelcake

+0

임시 테이블/테이블 변수를 사용하여 결과를 저장 한 다음 거기에서 업데이트 할 수 있습니다. – Sundance

+0

@angelcake, 99가 있습니다.9 %의 확률로 업데이트를 반복 할 필요가 없습니다. 당신은 반복의 관점에서 생각해서는 안됩니다. 반복은 나쁜 것입니다. 성능에 비용이 듭니다. 세트로 조작하는 법을 배워야합니다. 반복은 마지막 도랑이고, 다른 연산은 작동하지 않습니다. – HLGEM

0

루프 내부에서 작성한 쿼리에 루프 변수 @Init를 사용하고 있지 않습니다. 루프가 실행되면 자동으로 레코드를 이동시키는 Cursor와 같은 동작을 기대하고 있다고 생각합니다. 그런 것은 없습니다.

루프 내에서받는 값을 기반으로 테이블을 쿼리하는 방법을 찾아야합니다. 또는 쿼리를 작성하여 매번 상위 1 값을 가져 와서 임시 테이블에 넣고 쿼리에 NOT IN 절을 포함시켜 임시 테이블에없는 최상위 값을 조회하고 가져옵니다 (즉, 이미 페치 된 제외) .

관련 문제