Как я могу заставить триггер ждать? - PullRequest
0 голосов
/ 06 июня 2018

У меня есть проблема, которую я не могу решить, у меня есть точка продажи, которая вставляет 3 таблицы после продажи чего-либо, таблицу заголовков, детали и клиентов (в таком порядке).

У меня есть сохраненныйпроцедура, которая вставляет последнюю запись в таблицу bak, в столбце «текст» он вставляет объединенные из 3 таблиц (это принципиально), в то же время у меня есть метод вещи, который собирает все детали в одну строку ссоответствующий заголовок (только одна строка на заголовок), при выполнении процедуры после вставки она работает нормально, но при выполнении с триггером появляется ошибка, что нулевое значение не может быть вставлено в столбец «текст», это потому, чтотриггер указывает на заголовок таблицы и на другие 2 таблицы, которые не заполняются, если я укажу это на уровне детализации, метод stuff не будет работать (поскольку он вставляет одну запись в заголовок), идея состоит в том, чтобы указать наЗаголовок таблицы, но подождите, пока все не будет завершено, есть ли способ сделать это?Я ничего не могу коснуться с точки продажи, все было бы на уровне базы данных (SQL SERVER 2008), что-то можно сделать?Может ли триггер быть отложен так, чтобы он ожидал завершения заполнения двух других таблиц?

- INTERMEDIATE TABLE

CREATE TABLE [bak]
(
    [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [date] [date] NOT NULL,
    [serie] [varchar](2) NOT NULL,
    [text] [varchar](6000) NOT NULL
);

-ПРОЦЕДУРА МАГАЗИНА

CREATE PROCEDURE sp_bak
AS
BEGIN
  ;
  WITH CTE
  AS (SELECT
    h.date InsertDate,
    h.series DocumentSerie,
    ('349891894' + h.date + h.series + h.total +
    h.type + CHAR(13) + CHAR(10)) HeaderData,
    (d.quantity + d.price + d.description + c.name + 
    c.identification) DetailData
  FROM header h
  FULL JOIN detail d
    ON a.cod = b.cod
  FULL JOIN customers c
    ON b.cod = c.cod)
  INSERT dbo.bak (date, serie, text)
    SELECT TOP 1
      InsertDate,
      DocumentSerie,
      HeaderData + REPLACE(STUFF((SELECT
        ';' + DetailData
      FROM CTE C
      WHERE C.HeaderData = T.HeaderData
      FOR xml PATH ('')), 1, 1, ''), ';', CHAR(13) + CHAR(10))
    FROM CTE T
    GROUP BY HeaderData,
             DocumentSerie,
             InsertDate
  order by InsertDate DESC
END

- ТРИГГЕР

CREATE TRIGGER dbo.tr_bak
ON dbo.header
AFTER INSERT
AS
BEGIN
    EXEC sp_bak
END
GO

- ОШИБКА

Msg 515, Level 16, State 2, Procedure sp_bak, Line 4
Cannot insert the value NULL into column 'text', table 'VIDEOJUEGOS.dbo.bak'; column does not allow nulls. INSERT fails.

Ответы [ 2 ]

0 голосов
/ 26 июля 2019

У меня недавно был похожий сценарий.Триггер должен проверить, есть ли какая-либо запись в отдельной таблице для вложения файла, и я просто хочу запустить триггер только тогда, когда есть какое-либо новое вставленное вложение.Но мой триггер сработал еще до того, как таблица вложений была заполнена.Я попытался переместить триггер в таблицу вложений, но настоящей проблемой является ошибка timeout expired, выдаваемая SQL Server, когда триггер вызывает веб-API.Очевидно, что для этого требуется асинхронная обработка.

Вы, конечно, не можете просто добавить WAITFOR DELAY в свою процедуру, как указано в комментариях к предыдущему ответу.

Что вы можете сделать, это создать асинхроннуюактивировать с помощью service broker.И тогда вы можете использовать WAITFOR DELAY, чтобы заставить вашу хранимую процедуру QUEUE ACTIVATION ждать.Так что триггер по умолчанию не может ждать, пока вы не сделаете его асинхроннымИ это сработало для меня.

0 голосов
/ 06 июня 2018

В вашей хранимой процедуре для sp_bak вы можете иметь первый оператор:

WAITFOR DELAY '00:00:05'

Время может быть любым числом секунд, но этого достаточно, пока другие таблицы не будут вставлены со значениями.Вышеуказанные операторы задерживают выполнение операторов после WAITFOR на 5 секунд.Имейте в виду, что это не может быть хорошим способом решения такого рода проблем, потому что, если время задержки слишком велико, запуск может занять некоторое время и вызвать задержку операций.

...