Разница между PRINT @@ ROWCOUNT и OUTPUT $ ACTION на sql сервере - PullRequest
0 голосов
/ 03 марта 2020

Извинения, если мой вопрос кажется наивным: я не могу разобраться с двумя утверждениями ниже, может кто-нибудь объяснить, пожалуйста, разницу:

OUTPUT $ACTION, INSERTED.BuildRequestID, ..... and
PRINT @@ROWCOUNT

Очевидно, они оба могут быть использованы для печати чего-то на В окне, с выводом в примере выше, будут отображены вставленные записи. И PRINT @@ ROWCOUNT возвращает количество строк, на которые воздействовал последний выполненный оператор в пакете, поэтому, если функция была вставлена, то она будет показывать вставленные записи?

Спасибо,

1 Ответ

1 голос
/ 03 марта 2020

Проще говоря, OUTPUT даст вам фактические записи, затронутые оператором DML (INSERT, UPDATE, DELETE, MERGE), @@ROWCOUNT просто скажет Вы, сколько строк было затронуто предыдущим оператором (не ограничиваясь DML).

Это, вероятно, проще всего понять из рабочего примера, который вы можете запустить самостоятельно и увидеть оба в действии:

IF OBJECT_ID(N'tempdb..#T', 'U') IS NOT NULL
    DROP TABLE #T;

-- CHECK @@ROWCOUNT
DECLARE @RowCountFromDropTable INT = @@ROWCOUNT;

-- CREATE A TABLE
CREATE TABLE #T (ID INT NOT NULL PRIMARY KEY, Col CHAR(1) NOT NULL);

-- INSERT SOME VALUES AND CHECK THE OUTPUT
INSERT #T (ID, Col) 
OUTPUT inserted.*
VALUES (1, 'A'), (2, 'B'), (3, 'C');

-- CHECK @@ROWCOUNT
DECLARE @RowCountFromInsert INT = @@ROWCOUNT;

-- DELETE A VALUE AND INSPECT THE DELETED RECORD WITH OUTPUT
DELETE  #T
OUTPUT deleted.*
WHERE   ID = 3;

-- CHECK @@ROWCOUNT
DECLARE @RowCountFromDelete INT = @@ROWCOUNT;

-- UPDATE A RECORD AND VIEW BEFORE AND AFTER VALUES
UPDATE  #T
SET     Col = 'X'
OUTPUT inserted.ID AS ID, 
        inserted.Col AS UpdatedTo, 
        deleted.Col AS UpdatedFrom
WHERE   ID = 2;

-- CHECK @@ROWCOUNT
DECLARE @RowCountFromUpdate INT = @@ROWCOUNT;

-- USE MERGE, AND CAPTURE ACTION:
MERGE #T AS t
USING (VALUES (2, 'B'), (3, 'C')) AS s (ID, Col)
    ON s.ID = t.ID
WHEN NOT MATCHED THEN INSERT (ID, Col) VALUES (s.ID, s.Col)
WHEN MATCHED THEN UPDATE SET Col = s.Col
WHEN NOT MATCHED BY SOURCE THEN DELETE
    OUTPUT $Action AS DMLAction, 
            inserted.ID AS InsertedID, 
            inserted.Col AS InsertedCol, 
            deleted.ID AS DeletedID, 
            deleted.Col AS DeletedCol;

-- CHECK @@ROWCOUNT
DECLARE @RowCountFromMerge INT = @@ROWCOUNT;

SELECT  RowCountFromDropTable = @RowCountFromDropTable,
        RowCountFromInsert = @RowCountFromInsert,
        RowCountFromDelete = @RowCountFromDelete,
        RowCountFromUpdate = @RowCountFromUpdate,
        RowCountFromMerge = @RowCountFromMerge;

Наборы записей, выводимые каждым DML:

INSERT

ID  Col
-------
1   A
2   B
3   C

DELETE

ID  Col
-------
3   C

ОБНОВЛЕНИЕ

ID  UpdatedTo   UpdatedFrom
---------------------------
2       X           B

MERGE

DMLAction   InsertedID  InsertedCol DeletedID   DeletedCol
------------------------------------------------------------
INSERT          3           C           NULL        NULL
DELETE          NULL        NULL        1           A
UPDATE          2           B           2           X

INSPECT @@ ROWCOUNTS

RowCountFromDropTable   RowCountFromInsert  RowCountFromUpdate  RowCountFromMerge
--------------------------------------------------------------------------------
        0                       3                   1                   3

Небольшое замечание по поводу некоторых формулировок в qeuration: вы не можете использовать OUTPUT напрямую для печати чего-либо в окне, оно возвращает записи, очень похожие на оператор SELECT. @@ROWCOUNT может использоваться как любая скалярная функция, поэтому вы можете использовать это в последовательных утверждениях. Таким образом, вы можете сделать что-то вроде этого:

SELECT  TOP (1) *
FROM    (VALUES (1), (2), (3)) AS t (ID);

SELECT  TOP (@@ROWCOUNT + 1) *
FROM    (VALUES (1), (2), (3)) AS t (ID);

SELECT  TOP (@@ROWCOUNT + 1) *
FROM    (VALUES (1), (2), (3)) AS t (ID);

, который возвращает 1, 1,2 и 1,2,3 соответственно. Я понятия не имею, почему вы хотели бы сделать это, но он демонстрирует область действия @@ROWCOUNT немного лучше, чем выше, и как его можно использовать в другом месте.

...