Почему «Подзапрос возвратил более 1 значения. Это не разрешено ..» для того же запроса в триггере, а не как обычный запрос выполнения - PullRequest
2 голосов
/ 20 октября 2010

Я все еще пытаюсь получить правильные триггеры, но когда работает, кажется, что другие запускаются (не работают) снова. Раздражает .. но и воспитательно: -)

Когда я выполнил следующий SQL-запрос на сервере MS SQL, он успешно завершен, но когда он выполняется в триггере AFTER UPDATE, он завершается с ошибкой

Сообщение 512, Уровень 16, Состояние 1, Процедура TR_PHOTO_AU, строка 37 Подзапрос возвращен более 1 значение. Это не разрешено, когда подзапрос следует =, ! =, <, <=,>,> = или когда подзапрос используется в качестве выражения.

SQL;

        UPDATE p2
        SET p2.esb = '0'
        FROM ( SELECT TOP(5) p1.esb 
               FROM SOA.dbo.photos_TEST  p1
               WHERE  p1.esb = 'Q'
               ORDER BY p1.arrivaldatetime ASC 
        ) p2

Почему нельзя использовать подзапрос в качестве выражения в триггере? И есть ли обходной путь?

еще раз спасибо, Питер

Ответы [ 2 ]

1 голос
/ 20 октября 2010

Решение нужно было искать в совершенно другом направлении, я случайно определил мой триггер как триггер после вставки, обновления вместо триггера после обновления.Следующее определение триггера теперь работает

CREATE TRIGGER TR_PHOTO_AU
   ON       SOA.dbo.photos_TEST
   AFTER    UPDATE
AS 

DECLARE @MAXCONC INT  -- Maximum concurrent processes
DECLARE @CONC INT     -- Actual concurrent processes

SET @MAXCONC = 1      -- 1 concurrent processes

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON

-- If column esb is involved in the update, does not necessarily mean
-- that the column itself is updated
If ( Update(ESB) )
BEGIN
    -- If column esb has been changed to 1 or Q
    IF ((SELECT esb FROM INSERTED) in ('1','Q'))
    BEGIN
        -- count the number of (imminent) active processes
        SET @CONC = (SELECT COUNT(*) 
                  FROM SOA.dbo.photos_TEST pc
                  WHERE pc.esb in ('0','R'))

        -- if maximum has not been reached
        IF NOT ( @CONC >= @MAXCONC )
        BEGIN
            -- set additional rows esb to '0' to match @MAXCONC
            UPDATE TOP(@MAXCONC-@CONC) p2
            SET p2.esb = '0'
            FROM ( SELECT TOP(@MAXCONC-@CONC) p1.esb 
                   FROM SOA.dbo.photos_TEST  p1
                   WHERE  p1.esb = 'Q'
                   ORDER BY p1.arrivaldatetime ASC 
            ) p2

        END
    END
END
0 голосов
/ 20 октября 2010

Можете ли вы попробовать это?Обязательно укажите все свои столбцы PK как равные в WHERE внутри предложения EXISTS.

UPDATE  p1
SET     p1.esb = '0'
FROM    SOA.dbo.photos_TEST p1
WHERE   EXISTS ( SELECT TOP 5
                        *
                 FROM   SOA.dbo.photos_TEST p2
                 WHERE  p1.<KEYFIELD> = p2.<KEYFIELD>
                        AND p2.esb = 'Q'
                 ORDER BY p1.arrivaldatetime ASC )
...