Триггеры Внутреннее соединение вставлено с оригинальной таблицы - PullRequest
0 голосов
/ 23 февраля 2020

Я проверял создание триггеров DML в SQL Сервер в SQL Документах: Использование вставленных и удаленных таблиц

Есть пример, который делает следующее:

В следующем примере создается триггер DML. Этот триггер проверяет, что кредитный рейтинг поставщика является хорошим, когда делается попытка вставить новый заказ на покупку в таблицу PurchaseOrderHeader. Чтобы получить кредитный рейтинг поставщика, соответствующий только что вставленному заказу на поставку, необходимо сослаться на таблицу поставщиков и соединить ее со вставленной таблицей. Если кредитный рейтинг слишком низкий, отображается сообщение, и вставка не выполняется.

Обратите внимание, что в этом примере не допускается изменение многострочных данных.

USE AdventureWorks2012;
GO

IF OBJECT_ID ('Purchasing.LowCredit','TR') IS NOT NULL
   DROP TRIGGER Purchasing.LowCredit;
GO

-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table
-- when the credit rating of the specified vendor is set to 5 (below average).

CREATE TRIGGER Purchasing.LowCredit 
ON Purchasing.PurchaseOrderHeader
AFTER INSERT
AS
    IF EXISTS (SELECT *
               FROM Purchasing.PurchaseOrderHeader p 
               JOIN inserted AS i ON p.PurchaseOrderID = i.PurchaseOrderID 
               JOIN Purchasing.Vendor AS v ON v.BusinessEntityID = p.VendorID
               WHERE v.CreditRating = 5)
    BEGIN
        RAISERROR ('A vendor''s credit rating is too low to accept new purchase orders.', 16, 1);
        ROLLBACK TRANSACTION;
        RETURN 
    END;
GO

I Интересно, почему внутренний пример соединяет таблицу inserted с таблицей Purchasing.PurchaseOrderHeader, а затем присоединяется к таблице vendor.

Можно ли получить тот же результат, используя только таблицу inserted, соединяющую таблицу поставщиков напрямую, без соединение с Purchasing.PurchaseOrderHeader таблицей?

1 Ответ

0 голосов
/ 24 февраля 2020

Я не только считаю, что вы правы, я думаю, что на этой странице документации есть и другие неточности - я должен признать, что это довольно редко в моем опыте.

Возьмем, к примеру, эту часть:

Обратите внимание, что этот пример не допускает многострочных модификаций данных.

Это ложное утверждение. Пример кода триггера будет обрабатывать как вставку нескольких строк, так и вставку одной строки.

Обратите внимание, что в соответствии с задокументированным (и наблюдаемым) поведением вставленная таблица будет содержать все строки, вставленные (или обновленные) в Таблица назначения триггера:

Вставленная таблица хранит копии затронутых строк во время операторов INSERT и UPDATE. Во время транзакции вставки или обновления новые строки добавляются как во вставленную таблицу, так и в таблицу триггеров. Строки во вставленной таблице являются копиями новых строк в таблице триггеров.

Поэтому в этом случае должно быть достаточно объединения с inserted, чтобы обеспечить соблюдение обсуждаемого бизнес-правила.

При этом использование триггеров для обеспечения соблюдения бизнес-правил может оказаться трудным и даже проблематичным c - обратите внимание, что этот триггер охватывает только вставленные строки, но не обновленные строки. Это означает, что новая строка может быть вставлена ​​с допустимыми значениями, а затем обновлена ​​до недопустимых значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...