2012-12-19 2 views
1

아래에 저장 프로 시저가 있는데 도움이 필요합니다. 그 목적은 준비 DB와 프로덕션 DB 간의 차이점을 찾는 것입니다. 차이점을 발견하면 저장 프로시 저는 프로덕션 DB를 올바른 정보로 업데이트합니다. 문제는 때때로 DB 사이에 하나 이상의 차이가 있다는 것입니다. 저장 프로시 저는 한 번에 하나의 DB 차이 만 처리 할 수 ​​있습니다. 저장 프로 시저가 찾은 많은 차이점을 처리 할 수 ​​있기를 원합니다. 한 번에 하나의 차이 만 처리 할 수 ​​있으면 저장 프로 시저가 계속 실행되어야합니다. 어떤 아이디어 나 도움을 주시면 대단히 감사하겠습니다.DECLARE 문의 하위 쿼리가 두 개 이상의 값을 반환합니다.

  `BEGIN TRANSACTION 

      DECLARE @FILENUM NVARCHAR(30) 

      SET @FILENUM = (SELECT TOP 1 B.ID FROM DBO.ABC_FILE_NUMBER F WITH (NOLOCK) 

          JOIN DBO.REL_PRIMARY_NUMBER R WITH (NOLOCK) ON F.ID = R.FILE_NUMBER_ID 

          JOIN DBO.ABC_PRIMARY_NUMBER P WITH (NOLOCK) ON R.PRIMARY_NUMBER_ID = P.ID 

          JOIN DBO.STAGINGDATA S WITH (NOLOCK) ON F.FILE_NUMBER_ALIAS = S.ID 

          WHERE S.PRIMARYNUMBER <> P.PRIMARY_NUMBER_ALIAS) 

      DECLARE @PRIMNUM NVARCHAR(30) 

      SET @PRIMNUM = (SELECT DISTINCT P.ID FROM DBO.STAGINGDATA S WITH (NOLOCK) 

          JOIN DBO.ABC_PRIMARY_NUMBER P WITH (NOLOCK) ON P.PRIMARY_NUMBER_ALIAS = S.PRIMARYNUMBER 

          WHERE S.ID = (SELECT F.FILE_NUMBER_ALIAS FROM ABC_FILE_NUMBER WHERE ID = @FILENUM)) 

      UPDATE DBO.REL_PRIMARY_NUMBER 
      SET  PRIMARY_NUMBER_ID = @PRIMNUM 
      WHERE FILE_NUMBER_ID = @FILENUM 

      UPDATE DBO.ABC_WORKSPACE 
      SET  PRIMARY_NUMBER_ID = @PRIMNUM 
      WHERE FILE_NUMBER_ID = @FILENUM 

      UPDATE DBO.ABC_DOCUMENT 
      SET  PRIMARY_NUMBER_ID = @PRIMNUM 
      WHERE FILE_NUMBER_ID = @FILENUM 

      UPDATE DBO.ABC_FILE_NUMBER 
      SET  MODIFIED_TIME = GETDATE(), MODIFIED_BY_ID = '21403' 
      WHERE FILE_NUMBER_ID = @FILENUM 

      COMMIT` 

답변

0

는 각 @FILENUM을 통해 "도보"에 다음과 같이 루프를 구성하고 현재 사용중인 같은 스크립트를 사용하여 작업을 할 수 있습니다. 더 나은 옵션은 집합 기반 방식으로 작업을 수행하고 모든 행을 한꺼번에 처리하도록 각 DML 작업을 다시 작성하는 것이지만 수행중인 다른 작업에 따라 옵션이 아닐 수도 있습니다.

다음은 각 FileNum을 통해 루프에 대한 간단한 설치는 다음과 같습니다

declare @Process table (ProcessId int identity(1,1), FileNum nvarchar(30)); 

-- stage *all* the fileNums (perhaps in some order?) 
insert into @Process (FileNum) 
    SELECT B.ID FROM DBO.ABC_FILE_NUMBER F WITH (NOLOCK) 
    JOIN DBO.REL_PRIMARY_NUMBER R WITH (NOLOCK) ON F.ID = R.FILE_NUMBER_I 
    JOIN DBO.ABC_PRIMARY_NUMBER P WITH (NOLOCK) ON R.PRIMARY_NUMBER_ID = P.ID 
    JOIN DBO.STAGINGDATA S WITH (NOLOCK) ON F.FILE_NUMBER_ALIAS = S.ID 
    WHERE S.PRIMARYNUMBER <> P.PRIMARY_NUMBER_ALIAS 


declare @ProcessId int, 
     @FileNum nvarchar(30); 

select @ProcessId = min(ProcessId) from @Process; 

while @ProcessId is not null 
begin 

    select @FileNum = FileNum from @Process where ProcessId = @ProcessId; 

    print 'Working on FileNum: ' + @FileNum; 
    /* 
     do your work here 
    */ 

    select @ProcessId = min(ProcessId) from @Process where ProcessId > @ProcessId; 

end 

기반 작업이 같은 보일 것이다 세트 :

declare @Stage table (FileNum nvarchar(30), PrimNum nvarchar(30) primary key (FileNum)); 

-- stage the (FileNum:PrimNum) dataset 
insert into @Stage (FileNum) 
    select FileNum, PrimNum from dbo.yourTables where yourColumn ... 

--now perform set based updates 
UPDATE rpn 
SET  PRIMARY_NUMBER_ID = s.PRIMNUM 
from @Stage s 
join DBO.REL_PRIMARY_NUMBER rpn on 
     s.FileNum = rpn.FILE_NUMBER_ID 

UPDATE aw 
SET  PRIMARY_NUMBER_ID = s.PRIMNUM 
from @Stage s 
join DBO.ABC_WORKSPACE aw on 
     s.FileNum = aw.FILE_NUMBER_ID 

-- and so on...