Sql Server печатает затронутые строки во время цикла - PullRequest
6 голосов
/ 15 января 2010

У меня есть хранимая процедура, запущенная на sql server 2008, с циклом обработки таблицы из ~ 50 миллионов строк, удаляющих записи по одному за день (около 25 000 записей в день) Я хочу иметь возможность наблюдать, как это происходит, когда процесс выполняется через операторы печати в окне сообщений. Я хотел бы иметь возможность видеть сообщение каждый раз, когда за день фиксируется удаление. Есть ли способ сделать что-то подобное? Процедура примерно выложена так:

WHILE EXISTS(<query statement>)
BEGIN

BEGIN TRAN

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

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

COMMIT

END

Ответы [ 6 ]

23 голосов
/ 15 января 2010

К сожалению, вывод инструкции PRINT помещается в буфер и сразу не записывается в вывод. Чтобы обойти это, используйте RAISERROR следующим образом:

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

Специально для того, что вы хотите:

    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

Я также склонен включать текущее время в сообщение, чтобы я мог записывать прогресс по времени.

2 голосов
/ 15 января 2010

Что-нибудь более сложное, чем select @@ rowcount?

0 голосов
/ 08 декабря 2017

вы можете сделать что-то подобное, чтобы перебрать каждую строку

           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 =@@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 =@@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
0 голосов
/ 19 сентября 2013

Выполните следующие действия:

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 голосов
/ 15 января 2010

Раньше я делал что-то похожее на это, и потому что распечатки там, где он был помещен в буфер, было не очень полезным, однако я обнаружил, что утилита командной строки osql выводит их немедленно, поэтому я написал сохраненный процесс и вызвал его вместо этого пакетный файл, который позволяет мне видеть прогресс.

0 голосов
/ 15 января 2010

Как насчет использования предложения OUTPUT ?? Можете ли вы написать на консоль 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...