Каков надежный способ вернуть количество записей, вставленных из хранимой процедуры - PullRequest
2 голосов
/ 21 октября 2011

Я использую INSERT Trigger для этой таблицы. После запуска триггера (он обновляет таблицу, если выполняется условие), вот в чем проблема.

  int records = sc.ExecuteNonQuery(); // works ok if trigger does not update the record

Приведенный выше код всегда возвращается -1, если я оставлю SET NOCOUNT ON; в самой хранимой процедуре. Если я удаляю его, я получаю правильный результат, но если триггер обновляет запись, то неверный результат. Я иногда получаю 10 или другое число. Мой триггер выглядит так

UPDATE students 
    SET status = 'Inactive'

    FROM Inserted i
        INNER JOIN students T2
            ON i.sname = T2.sname
            AND i.id <> t2.id

Это означает, что он может возвращать более одной записи (особенно в тестовых случаях). Может кто-нибудь сказать мне, что такое лекарство? Я открыт для использования функций, если это решает проблему или любой другой подход.

Спасибо

Добавление вставки SP

CREATE PROCEDURE sp_InsertSudent 
    -- Add the parameters for the stored procedure here
    @student_name varchar(25) = null, 
    @status varchar(20) = null,
    @renew varchar(15) = null,
    @edate datetime = null
AS
BEGIN

    --SET NOCOUNT ON;

    insert into students VALUES(@student_name,@status,@renew,@edate)


END
GO

Примечание. Я ищу ошибку, поскольку поля выбраны из Excel. если какое-либо поле имеет неправильный формат или не заполнено, Insert SP выдаст ошибку. Я должен передать эту ошибку пользователю.

Добавление фактического SP

Так что вся проблема в SP. Если я уберу его, все будет нормально. Вот мой актуальный SP

UPDATE CustomerTbl
SET [Account Status] = 'Inactive',
    [End Date] = DateAdd(day,-1,[Supplier End Date]),
    [EnrollmentStatus] = 'Waiting'
WHERE OET.[Account No] = (SELECT [Account No] FROM CustomerTbl WHERE id = @@identity)
  AND id <> @@identity

Логика та же, что и выше, но изложена иначе. ExecuteNonQuery пропускает результат этого триггера, чем фактическая хранимая процедура, так что же он излечит? Может как-то подавить его вывод.

Ответы [ 4 ]

0 голосов
/ 06 сентября 2016

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

0 голосов
/ 21 октября 2011

Я бы добавил блоки Try Catch в процесс и вернул бы 1 в случае успеха и 0 в случае неудачи.

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

UPDATE students      
SET status = 'Inactive'      
FROM Inserted i         
INNER JOIN students T2             
    ON i.sname = T2.sname 
    AND i.id <> t2.id 
    AND status <> 'inactive'

Это может уберечь вас от обновления 1000 строк, когда вам действительно нужно обновить только одну активную строку.

0 голосов
/ 21 октября 2011

Мой собственный ответ (пока не полный). В соответствии с документацией MSDN для ExecuteNonQuery

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

Это означает, что мне нужно изменить сам триггер, чтобы он соответствовал логике, или даже тому факту, что когда триггер вызывается, это доказывает, что запись была успешной. Это означает, что если я получу что-то больше 0, это следует считать успехом. Хотя не сплошная логика, но это будет работать. SET COUNT ON необходимо прокомментировать для этого.

0 голосов
/ 21 октября 2011

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

поочередно, если вы пытаетесь вести подсчет общего числа затронутых записей (как вставками, так и обновлениями), то вы можете включить логику в триггер в ваш sproc. строки, затронутые как оператором вставки (всегда 1), так и оператором обновления (@@ rowcount после завершения обновления) ... затем вы можете вернуть это значение вызывающей стороне.

UPDATE: Конечно, верните 0, если есть ошибка. При использовании SQL2005 (или выше) используйте механизм TRY / CATCH.

...