2011-08-24 3 views
2

У меня есть следующий триггер. При вставке новой строки Хранимая процедура не может получить значение параметра переменной @ItemID. Я пытаюсь передать значение ItemID колонны вновь вставленной строки хранимой процедуры CalculateCurrentStockОшибка выполнения SQL Trigger

ALTER TRIGGER UpdateCurrentStock 
    ON StockIn 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    EXEC CalculateCurrentStock (SELECT ItemID From INSERTED) 
END 

Текст ошибки читает

Процедура или функция «CalculateCurrentStock» ожидает параметр «@ItemID», который не был поставлен. Заявление было прекращено.

Благодарим за помощь.

EDIT: Ответ

Я изменил триггер на Derek Кромм-х и предложение КМ в

ALTER TRIGGER UpdateCurrentStock 
    ON StockIn 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @CSV varchar(max) 
    SELECT @CSV=ISNULL(@CSV+',','')+ItemID From INSERTED 
    EXEC CalculateCurrentStock @CSV 


END 

Спасибо за помощь :)

+1

Marshal, что ISN Я предложил. Ваш модифицированный триггер будет работать, только если вы обновите одну строку. Если вы обновите несколько строк, это не сработает. –

+2

** ваше 'edit' не будет выполнено, если ваша таблица' INSERTED' содержит более одной строки. ** Лучше всего всегда писать триггеры для поддержки нескольких строк в 'INSERTED' и/или' DELETED'. Достаточно легко и просто вставлять/обновлять/удалять несколько строк в одном выражении, и любой триггер, который обрабатывает только одну строку, терпит неудачу «логическим» способом без сообщения об ошибке (ваши данные перепутались). попробуйте что-то подобное, чтобы ваш триггер не сработал: INSERT INTO StockIn (col1, col2, ...) SELECT TOP 3 col1, col2, ... FROM StockIn ORDER BY ItemID 'this предполагает, что ItemID является идентификатором PK. –

+0

Я отредактировал ответ. Спасибо Derek и KM за ценные входы – Marshal

ответ

2

Я лично высунул свой глаз перед тем, как использовать курсор, особенно когда вы можете передать набор значений (параметр табличных значений или CSV) за один раз за один вызов процедуры.

Если вы используете SQL Server 2008, вы можете создать свою процедуру с помощью Table-Valued Parameters и должны быть в состоянии пройти в таблице INSERTED.

Если вы используете SQL Server 2005, вы можете создать список значений с запятой (csv) в переменной varchar (max) и передать это в вашу процедуру.

EDIT, вот как пройти в CSV

ALTER TRIGGER UpdateCurrentStock 
    ON StockIn 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    DECLARE @CSV varchar(max) 
    SELECT @CSV=ISNULL(@CSV+',','')+ItemID From INSERTED 
    EXEC CalculateCurrentStock @CSV 
END 

теперь в пределах вам нужно разделить на части значения @CSV, так что смотрите здесь: Pass a list-structure as an argument to a stored procedure

+0

@KM: Я использую SQL Server 2005. Итак, в моем конкретном случае я могу преобразовать '(SELECT ItemID FROM INSERTED)' в значения CSV? – Marshal

3

Edit: Как Мартин отметил, вы можете передать параметр таблицы, если используете SQL Server 2008. Если вы используете 2005 или ранее, вы не можете этого сделать. В этом случае KM предлагает использовать значение с разделителями-запятыми, с чем я лично не согласен.

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

+0

Прошу прощения, я новичок в SQL.Я не понимаю, что я должен поставить для '<объявить/открыть курсор из вставленных>' и '<закрыть/деактивировать курсор>'. Еще раз спасибо за помощь – Marshal

+0

см. Редактировать, например –

+0

Вы видели мое редактирование? Это работы в настоящее время. Является ли ваш код более безопасным в исполнении? – Marshal