2016-06-16 2 views
0

Я не могу получить то, что должно быть простым триггером для работы. Он запускается после INSERT, проверяет, является ли столбец A нулевым, и если он устанавливает его в значение столбца B этой же строки. После вставки я проверяю вставленную строку, а столбец B имеет значение, но столбец A имеет значение NULL. Триггер включен и уволен, потому что в отчаянии я записывал значения в рабочий стол в разных точках, , и эти значения являются ожидаемыми.Что я делаю неправильно с этим триггером SQL Server 2012?

Я даже попытался сделать временный обход этой проблемы, перейдя в раздел «Дизайн» в этой таблице и указав «значение по умолчанию» 1000 для этого столбца, но он все равно имеет значение null. И я попробовал сменить триггер, чтобы установить столбец А в фиксированное значение 987, но он все равно выходит нулевым.

Есть ли какая-то особенность о вставках, о которых я не знаю? Любые советы приветствуются.

ПРЕДПОСЫЛКИ ---------------------------------------------- --------------------------------

ОПЦИИ - это таблица, в которой хранятся «Варианты», которые участники на одном (например, билет на мероприятие, дополнительный обед из стейка или курятины и т. д.) Эти параметры вставляются, когда событие определяется (даты, места проведения, контактные данные и параметры, которые посетители могут зарегистрируйтесь).

Параметры таблицы:

OptionID INT (Identity, primary key) 
... 
MaxAttendees INT 
... 
AvlbRemainingRegQty INT 

Этот последний столбец является не получаю набор - это должно быть бегущая в общей сложности, сколько куриные обеды остальные должны быть проданы

Я думал, сошел с ума и/или сделал что-то глупое, поэтому я создал таблицу zTestTrigger для хранения значений из строки INSERTED и для проверки того, что триггер попал в определенные моменты.

WhichPartOfTest VARCHAR(100) 
OptionID  INT 
AvlbRemRegQty INT 
MaxAttendees INT 

- ПОДРОБНОСТИ ---------------------------------------- -----------

USE [dbname] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[trig_Options_AvlbRemainingRegQty] 
ON [dbo].[Options] 
AFTER INSERT 
AS 
SET NOCOUNT ON 

DECLARE @I_OptionID INT 
DECLARE @I_AvlbRemainingRegQty INT 
DECLARE @I_MaxAttendees INT 

SELECT 
    @I_OptionID   = I.OptionID, 
    @I_AvlbRemainingRegQty = ISNULL(I.AvlbRemainingRegQty,-1), 
    @I_MaxAttendees  = MaxAttendees 
FROM Inserted I 

insert into zTestTrigger values ('Start of new test - values from INSERTED row are:',@I_OptionID, @I_AvlbRemainingRegQty, @I_MaxAttendees) 

IF ISNULL(@I_AvlbRemainingRegQty,-1) = -1 --(I had also tried checking IF I_AvlbRemainingRegQty IS NULL) 

    begin 

    insert into zTestTrigger values ('About to update table, setting AvlbRemQty = ' + cast(@I_MaxAttendees as varchar) + ' where id = ' + cast(@I_OptionID as varchar), 
@I_OptionID, @I_AvlbRemainingRegQty, @I_MaxAttendees) 

    UPDATE Options SET AvlbRemainingRegQty = @I_MaxAttendees WHERE OptionID = @I_OptionID 

    --Originally, I tried this: 
    --UPDATE OPTIONS SET AvlbRemainingRegQty = ISNULL(MaxAttendees,1000) WHERE OptionID = @I_OptionID 
    --This doesn't work either: 
    --UPDATE OPTIONS SET SET AvlbRemainingRegQty = SELECT ISNULL(MaxAttendees,1000) FROM Options WHERE OptionID = @I_OptionID) WHERE OptionID = @I_OptionID 
    --I even tried: 
    --UPDATE OPTIONS SET AvlbRemainingRegQty = 987 WHERE OptionID = @I_OptionID 

    declare @error int 
    set @error = @@ERROR 
    insert into zTestTrigger values ('@@ERROR is ' + cast(@error as varchar), 0,0,0) --Shows that @Error is 0 

    end 

Выбор из таблицы zTestTrigger показывает

"About to update table, setting AvlbRemQty = 1000 where id = 491" , 491, -1, and 1000 

и я могу выбрать строку с ID 491, но его AVLB Rem Кол-равно нулю.

ответ

1

Я бы лично использовал для этого instead of триггер, поскольку он позволяет нам правильно вводить данные с самого начала.

Но сейчас мы будем делать после запуска:

ALTER TRIGGER [dbo].[trig_Options_AvlbRemainingRegQty] 
ON [dbo].[Options] 
AFTER INSERT 
AS 
    SET NOCOUNT ON 

    UPDATE Options 
    SET 
     AvlbRemainingRegQty = COALESCE(AvlbRemainingRegQty, MaxAttendees) 
    WHERE 
     OptionID in (select OptionID from inserted) 

И заметьте, что этого триггера (в отличие от вас) признает, что inserted может содержать 0, 1 или Множественные строк. Поэтому обработайте его как таблицу, а не как нечто, из которой отдельные, скалярные переменные могут иметь значащие значения.

Подобно тому, как другой точки, хотя:

он должен быть запущен в общей сложности, сколько куриные обеды остальные должны быть проданы

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

+0

Благодарим за предложение ... но вставку INSTEAD OF тоже не было никакого эффекта.

asdf –

+0

Ack, взял <> 5 минут, чтобы ответить, поэтому он потерял отредактированный вами комментарий. Ваш предлагаемый код должен работать, но col все еще не обновляется. Триггер INSTEAD OF запустил ошибку, которую я рассмотрю дальше. Я просто отчасти ошеломлен - что-то действительно основное не так. Кстати, я согласен с вашим вторым моментом, но парень, с которым я делаю это, является старшим в нашем маленьком магазине и не заботится о нормализации данных. –

Смежные вопросы