Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 返回使用IF语句时更改了多少行?_Sql_Sql Server_Sql Update_Rowcount - Fatal编程技术网

Sql 返回使用IF语句时更改了多少行?

Sql 返回使用IF语句时更改了多少行?,sql,sql-server,sql-update,rowcount,Sql,Sql Server,Sql Update,Rowcount,我正在SQL中运行一些update语句,我想返回一个审计表,看看有多少行受到了影响。现在我了解并看到了可以使用@@ROWCOUNT执行此操作的示例。问题是我正在使用带有IF语句的update语句 BEGIN TRANSACTION WHILE 1=1 BEGIN BEGIN TRANSACTION --update a 1000 rows at a time UPDATE TOP (1000) table1 SET flag = 1,

我正在SQL中运行一些update语句,我想返回一个审计表,看看有多少行受到了影响。现在我了解并看到了可以使用@@ROWCOUNT执行此操作的示例。问题是我正在使用带有IF语句的update语句

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。我试着将它重新分配到一个不同的变量,但仍然没有乐趣

任何关于这方面的建议都会很好


如果需要更多信息,请询问:

使用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

如果您声明了一个可以工作的值,请确保您的变量范围

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

您可以尝试在下面的查询中插入datetime在审核表中受影响的记录,如下所示

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

希望这能对您有所帮助。

我放弃了第一笔交易,重新安排了一些部分。我在脚本的开头声明了2个变量。似乎您已经有了@audit table变量,所以您可能希望省略该部分。此脚本最重要的部分是它不会进入无休止的循环,只更新行,而不将标志设置为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
我不会使用while1=1,而是使用一个更符合逻辑的循环,如下所示。 这永远不应该成为一个无限循环,它应该在审计表中正确写入,而不需要中断构造

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

IF语句与更新无关。还有,为什么在@ROWCOUNT=0时进行提交?在这种情况下,没有任何更新,那么为什么要提交呢?在我看来,似乎没有更新。当您执行select而不是update时会得到什么?我的理解是update语句一次执行1000行。如果有更多行要更新,则继续。如果none ROWCOUNT=0,则它将中断并结束。我过去所做的更新都是使用上述公式进行的。除非我运气好。除非我弄错了,否则这可以随机更新前1000行,因为您没有订单,但将在此停止。如果where子句中的行数超过1000行,则只更新前1000行,而不更新其他行。我的想法对不对?所以除非它在一个循环中,否则它将只更新1000 max,对吗?我在开始时使用while1=1。我应该把这个包括在上面。只是想把最基本的东西放在里面。我想这是我的SQL的绊脚石,因为@D-Shih answer工作得很好,但不是我的解决方案。这很好,除了上面的更新,我使用了一段时间,我认为这会影响结果,因为它会一次又一次地循环。对此有何想法?这也适用于我最初的问题。问题是我没有包括我在上面更新的while循环,它现在一次又一次地循环。第一个问题:这将进入无休止的循环,因为列表表永远不会是空的,除非它从一开始就是空的。第二个问题:第一个事务永远不会回滚任何内容。@t-clausen.dk这是复制/粘贴代码时得到的结果。修正了问题