Триггер TSQL не сохраняет переменные и / или не выполняет должным образом - PullRequest
1 голос
/ 29 ноября 2010

У меня проблемы с получением триггера TSQL для правильной работы.Я запустил его через отладчик, и он не устанавливает любые переменных в соответствии с SQL Server Management Studio.Самое ужасное, что сам триггер работает правильно, и при его выполнении ошибок нет (просто говорит «выполнение выполнено»).

Код выглядит следующим образом (это незавершенная работатолько знакомлюсь):

USE TestDb

IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'OfficeSalesQuotaUpdate' AND type = 'TR')
   DROP TRIGGER OfficeSalesQuotaUpdate
GO

CREATE TRIGGER OfficeSalesQuotaUpdate
ON SalesReps
AFTER UPDATE, DELETE, INSERT 
AS
    DECLARE @sales_difference int,  @quota_difference int
    DECLARE @sales_original int,    @quota_original int
    DECLARE @sales_new int,         @quota_new int

    DECLARE @officeid int
    DECLARE @salesrepid int

    --UPDATE(Sales) returns true for INSERT and UPDATE.
    --Not for DELETE though.    

    IF ((SELECT COUNT(*) FROM inserted) = 0)
        SET @salesrepid = (SELECT SalesRep FROM deleted)
    ELSE    
        SET @salesrepid = (SELECT SalesRep FROM inserted)   

    --If you address the @salesrepid variable, it does not work. Doesn't even 
    --print out the 'this should work line.
    PRINT 'This should work...' --+ convert(char(30), @salesrepid)

    IF (@salesrepid = NULL)
        PRINT 'SalesRepId is null'
    ELSE
        PRINT 'SalesRepId is not null'

    PRINT convert(char(50), @salesrepid)


    SET @officeid = (SELECT RepOffice 
                       FROM SalesReps 
                      WHERE SalesRep = @salesrepid)

    SELECT @sales_original =    (SELECT Sales FROM deleted)
    SELECT @sales_new =         (SELECT Sales FROM inserted)

    --Sales can not be null, so we'll remove this later.
    --Use this as a template for quota though, since that can be null.
    IF (@sales_new = null) 
    BEGIN
        SET @sales_new = 0
    END

    IF (@sales_original = 0)
    BEGIN
        SET @sales_original = 0
    END

    SET @sales_difference = @sales_new - @sales_original

    UPDATE Offices
    SET Sales = Sales + @sales_difference
    WHERE Offices.Office = @officeid
GO

Итак, есть какие-нибудь советы?Я полностью озадачен этим.Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 29 ноября 2010

Похоже, ваша основная проблема заключается в том, что существует разница между @foo = NULL и @foo IS NULL:

declare @i int
set @i = null -- redundant, but explicit

if @i = null print 'equals'
if @i is null print 'is'

Оператор PRINT «Это должно работать» не работает, потому что объединение NULL сСтрока дает значение NULL, а PRINT NULL ничего не печатает.

Что касается фактической установки значения @salerepid, то, скорее всего, вставленная и / или удаленная таблица фактически пуста.Какие утверждения вы используете для проверки триггера?И распечатали ли вы значение COUNT (*)?

Вам также следует подумать (если вы этого еще не сделали), что произойдет, если кто-то изменит более одной строки одновременно.Ваш текущий код предполагает, что за один раз изменяется только одна строка, что может быть разумным допущением в вашей среде, но он может легко сломаться, если кто-то массово загружает данные или выполняет другую «пакетную обработку».

Наконец,Вы всегда должны указывать свою версию и версию MSSQL;это может быть актуально для некоторых вопросов синтаксиса.

2 голосов
/ 29 ноября 2010

Вы должны заменить тело триггера чем-то вроде этого:

;WITH Totals AS (
     SELECT RepOffice,SUM(Sales) as Sales FROM inserted GROUP BY RepOffice
     UNION ALL
     SELECT RepOffice,-SUM(Sales) FROM deleted GROUP BY RepOffice
), SalesDelta AS (
     SELECT RepOffice,SUM(Sales) as Delta FROM Totals GROUP BY RepOffice
)
UPDATE o
SET Sales = Sales + sd.Delta
FROM
    Offices o
        inner join
    SalesDelta sd
        on
             o.Office = sd.RepOffice

Это будет адекватно работать с несколькими строками, вставленными и удаленными.Я предполагаю, что SalesRep является первичным ключом таблицы SalesReps.


Обновлен выше, чтобы справиться с UPDATE, изменяющим RepOffice конкретного торгового представителя (который, по-видимому, не является правильным в оригинале)либо)

0 голосов
/ 29 ноября 2010

Просто предложение ... Вы пытались поместить BEGIN и END для инкапсуляции части "AS" вашего триггера?

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