Возвращает, сколько строк изменилось при использовании оператора IF? - PullRequest
0 голосов
/ 29 октября 2018

Я выполняю некоторые операторы обновления в SQL и хочу вернуть в таблицу аудита, сколько строк было затронуто. Теперь я понимаю (и видел примеры), что для этого можно использовать @@ ROWCOUNT. Проблема в том, что я использую оператор обновления с оператором IF.

BEGIN TRANSACTION
WHILE 1=1
BEGIN
    BEGIN TRANSACTION 
        --update a 1000 rows at a time
        UPDATE TOP (1000) table1
        SET flag = 1,
        WHERE ID IN (SELECT ID FROM #list)      

            IF @@ROWCOUNT = 0 -- terminating condition
            BEGIN
                COMMIT TRANSACTION
                BREAK
            END

    COMMIT TRANSACTION
    WAITFOR DELAY '00:00:01';
END
--COMMIT TRANSACTION
ROLLBACK TRANSACTION
GO

Теперь я хочу использовать что-то вроде следующего.

INSERT INTO @Audit
SELECT 'table1', @@ROWCOUNT

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

Любые указатели на это были бы великолепны.

Если вам нужна дополнительная информация, пожалуйста, спросите:)

Ответы [ 5 ]

0 голосов
/ 29 октября 2018

Я бы не использовал while 1=1, но более логичный цикл, как этот.
Это никогда не должно становиться бесконечным циклом, и оно должно записываться правильно в вашей таблице аудита, без необходимости использования break конструкции.

declare @Audit table(tableName varchar(20), RowsUpdated int)
declare @RowsUpdated int = -1

WHILE @RowsUpdated <> 0
BEGIN
    BEGIN TRANSACTION 

    --update a 1000 rows at a time
    UPDATE TOP (1000) table1
    SET    flag = 1
    WHERE  ID IN (SELECT ID FROM #list)    
    AND    (flag <> 1 or flag is null)

    set @RowsUpdated = @@ROWCOUNT

    INSERT INTO @Audit
    SELECT 'table1', @RowsUpdated;

    COMMIT TRANSACTION
    WAITFOR DELAY '00:00:01';
END
GO
0 голосов
/ 29 октября 2018

Я отбросил первую транзакцию и переставил некоторые детали. Я объявил 2 переменные в начале скрипта. Кажется, у вас уже есть переменная таблицы @audit, так что вы можете пропустить эту часть. Наиболее важной частью этого скрипта является то, что он не входит в бесконечный цикл и обновляет только строки без установленного флага 1:

DECLARE @audit table(col1 varchar(20), rows int)
DECLARE @counter INT = 1000
WHILE @counter= 1000
BEGIN
    BEGIN TRANSACTION 
    --update a 1000 rows at a time
    ;WITH CTE as
    (
       SELECT distinct id
       FROM #list
    )
    UPDATE TOP (1000) t1
    SET flag = 1
    FROM table1 t1
    JOIN #list lst
    ON t1.ID = lst.id
    and (t1.flag <> 1 or t1.flag is null)
    SELECT @counter = @@ROWCOUNT
    INSERT INTO @Audit values('table1', @counter)
    COMMIT TRANSACTION
    WAITFOR DELAY '00:00:01';
END
0 голосов
/ 29 октября 2018

Если вы объявляете внешнее значение, оно может работать, убедитесь, что ваша область видимости переменной.

CREATE TABLE T(i int);
insert T values (1);
insert T values (1);
insert T values (1);

DECLARE @CountNum int -- if it set outside is ok

BEGIN
    BEGIN TRANSACTION 
       UPDATE TOP (1000) T
       SET i = 111

       SELECT @CountNum = @@ROWCOUNT

            IF @@ROWCOUNT = 0 -- terminating condition
            BEGIN
                COMMIT TRANSACTION

            END

    COMMIT TRANSACTION
    WAITFOR DELAY '00:00:01';
END



SELECT @CountNum

sqlfiddle

0 голосов
/ 29 октября 2018

Вы можете попробовать выполнить запрос ниже, чтобы вставить записи, затронутые в таблице аудита, с указанием даты и времени, как показано ниже.

CREATE TABLE #AuditTable (dtDateTime datetime default getdate(), NoOfRecords int)--Creating Audit Table
CREATE TABLE #Temp (sEmployeeName Varchar(50))
INSERT INTO #Temp VALUES ('A')
INSERT INTO #Temp VALUES ('B')
INSERT INTO #Temp VALUES ('C')
INSERT INTO #Temp VALUES ('D')
INSERT INTO #Temp VALUES ('E')
INSERT INTO #Temp VALUES ('F')

--SELECT * FROM #Temp --Before Update
UPDATE #Temp SET sEmployeeName = 'U - ' + sEmployeeName --Update

INSERT INTO #AuditTable (NoOfRecords) SELECT @@RowCount--No. of Records Updated

SELECT * FROM #AuditTable --Audit Table
DROP TABLE #Temp
DROP TABLE #AuditTable

Вывод как показано ниже

dtDateTime                 NoOfRecords
2018-10-29 18:05:11.280    6

Надеюсь, это поможет вам.

0 голосов
/ 29 октября 2018

Используйте переменную temp для хранения значения @@ ROWCOUNT. После проверки в строке IF это значение устанавливается равным 0.

DECLARE @MY_ROW_CNT AS INT;   
BEGIN
    BEGIN TRANSACTION 
    --update a 1000 rows at a time
    UPDATE TOP (1000) table1
    SET flag = 1,
    WHERE ID IN (SELECT ID FROM #list) 

    SET @MY_ROW_CNT = @@ROWCOUNT;


    IF @MY_ROW_CNT = 0 -- terminating condition
    BEGIN
      COMMIT TRANSACTION
      BREAK
    END

    INSERT INTO @Audit
    SELECT 'table1', @MY_ROW_CNT;

    COMMIT TRANSACTION
    WAITFOR DELAY '00:00:01';
END
...