2010-01-15 5 views
5

SQL Server 2008에서 실행되는 저장 프로 시저가 한 번에 하나씩 레코드를 삭제하면서 약 5 천만 행의 테이블을 반복합니다 (하루 약 25,000 레코드). 프로세스가 print 문을 통해 메시지 창으로 실행될 때이 문제를 볼 수 있기를 원합니다. 하루의 삭제 가치가 커질 때마다 메시지를 볼 수 있기를 바랍니다. 이런 식으로 할 수있는 방법이 있습니까? 절차는 다음과 같이 대략적으로 배열됩니다 :Sql 서버는 while 루프 중에 영향을받은 행을 인쇄합니다.

WHILE EXISTS(<query statement>) 
BEGIN 

BEGIN TRAN 

DELETE 
FROM <table> 
WHERE <condition> 
AND <condition> 

--need some sort of "rows affected" statement here 

COMMIT 

END 

답변

20

불행히도 PRINT 문 출력은 스풀 업되어 즉시 출력에 기록되지 않습니다. 이 라운드 방식은 다음과 같이 RAISERROR를 사용하는 것입니다

DECLARE @Msg VARCHAR(200) 

    WHILE EXISTS(<query statement>) 
    BEGIN 
    BEGIN TRAN 

    DELETE 
    FROM <table> 
    WHERE <condition> 
    AND <condition> 

    SELECT @Msg = CAST(@@ROWCOUNT AS VARCHAR(10)) + ' rows affected' 
    RAISERROR (@Msg, 0, 1) WITH NOWAIT 

    COMMIT 
    END 

나는 또한 내가 시간에 대한 진행 상황을 기록 할 수 있도록 메시지의 현재 시간을 포함하는 경향이 :

RAISERROR ('MY MESSAGE', 0, 1) WITH NOWAIT 

특히 당신이 원하는 무엇을.

+0

반복하는 이런 일을 할 수있는,하지만 난 여전히 각 배치 중 삭제에 의해 영향을받는 행의 수를 잡아하는 방법을 아주 확실하지 않다. 그것에 관한 어떤 생각? – Kevin

+1

@ 케빈 - 내 업데이트 참조 :) – AdaTheDev

+0

고마워! 이 작동합니다 :) – Kevin

2

select @@ rowcount보다 복잡한 것은 무엇입니까?

+0

멋지고 복잡하지 않습니다! – alfadog67

0

OUTPUT 절 사용 방법은 어떻습니까 ?? 저장된 proc에서 SQL Server 콘솔에 쓸 수 있습니까 ??

트리거와 마찬가지로 삭제 된 행과 모든 열이 포함 된 "삭제 된"의사 테이블이 있습니다.

WHILE EXISTS(<query statement>) 
BEGIN 
    BEGIN TRAN 

    DELETE FROM <table> 
    OUTPUT deleted.ID, deleted.TimeStamp -- or whatever 
    WHERE <condition> 
    AND <condition> 

    COMMIT 

END 
+0

배치 당 삭제 된 각 행을 반드시보고 싶지는 않지만 전체 개수 만보고 싶습니다. OUTPUT 절을 사용하여 해당 기능을 사용할 수 있는지 확신 할 수 없습니다. – Kevin

+0

OUTPUT을 임시 테이블로 지정하고 WHILE 루프 다음에 임시 테이블의 행을 계산할 수 있습니다. –

0

나는 이와 비슷한 일을하는 데 사용, 최대 스풀 인쇄가 훨씬 사용이 없었기 때문에, 그러나 나는 명령 행 유틸리티 osql 출력은 그 즉시, 그래서 나는이 저장된 프로 시저를 쓴 것을 발견하고 전화 대신 배치 파일에서 진행률을 볼 수 있습니다.

0

는 다음을 수행하십시오 유효성을 검사 할 경우, 다음과 같은 코드를 던질 수

DECLARE @queryCount AS INT, @start AS INT, @stop as INT, @table as varchar(max) 

SELECT @start = cnt(*) as a FROM <table> 

SELECT @queryCount = cnt(*) 
    FROM <table> 
    WHERE <condition> 
    AND <condition> 

DELETE 
    FROM <table> 
    WHERE <condition> 
    AND <condition> 

SELECT @stop = cnt(*) as a FROM <table> 

PRINT(convert(varchar(max), @queryCount) + ' rows deleted from ' + convert(varchar(max), @table)) 

.

PRINT('Rows at start: ' + convert(varchar(max), @start)) 
PRINT('Rows at end: ' + convert(varchar(max), @stop)) 
PRINT('Row difference: ' + convert(varchar(max), @start - @stop)) 

경고 :이 상황이 진행되는 동안 데이터베이스가 행에 영향을 줄 수있는 경우 불일치가 발생할 수 있습니다.

0

당신이 작동 각 행

  declare @ii (id int) table 

    -- for batchchunk operations  

      declare @numTransactions as int = 0,   
      @totalRowsInserted as int = 0,   
      @chunksize int = 0,   
      @printnow varchar(1000)  


     --does the initial insert into the table  
      select * from #table  
      SET @numTransactions [email protected]@rowcount  
      SET @printnow = 'Should Insert :'+cast(@numTransactions as varchar)+ ' rows into the table.'   
      exec db.printNow @printnow;  -- shortened proc 

      BEGIN   
      INSERTCHUNKS:   

      SET ROWCOUNT @Batchsize     



      insert into table     
      (     
      type_id,     
      parent_id,     
      created_by_user_id,     
      created_at,     
      updated_by_user_id,     
      updated_at,     
      created_by_system_id,     
      updated_by_system_id,     
      is_deleted     
      )     
      output inserted.id into @ii(id)     

      select     
      1,--party_type_id     
     NULL,--parent_party_id     
     @user_id, --created_by_user_id     
     case when created_at is NULL then getdate() else created_at end ,        

     NULL , --updated_by_user_id     
     case when updated_at is NULL then getdate() else updated_at end, -- 
     updated_at     
     case when created_by_system_id is null then 292 else 0 end, --created_by_system_id     
      updated_by_system_id,--updated_by_system_id     \ 
      0 --is_deleted     
     from     
     #table   
     order by id asc    
     OFFSET    
     @TotalRowsInserted ROWS   
     FETCH NEXT @batchsize ROWS ONLY  
     set @chunksize [email protected]@rowcount    
      IF @chunksize > 0  
      BEGIN    
     set @totalRowsInserted = @totalRowsInserted + @chunksize    
      SET @printnow = 'Batch done: ' + 
      cast(@chunksize as varchar) + ' rows in Batch ; '   
      + cast(@totalRowsInserted as varchar) + ' total inserted so far 
      into the table.'    exec db.printnow @printnow;    

      waitfor delay '00:00:01'   
      GOTO INSERTCHUNKS   
      END   
      SET ROWCOUNT 0;  
      END