Ошибка обработки ошибок с оператором обновления внутри хранимой процедуры - PullRequest
0 голосов
/ 29 апреля 2019

Я не могу понять, почему код не работает. В таблице vendorproducts есть данные, однако после выполнения данные не извлекаются, и при передаче @vendor=1

также не возникает ошибка печати.
ALTER PROCEDURE HW5UD1
    @vendor VARCHAR(64),
    @Perct DECIMAL(3,2)
AS
BEGIN TRANSACTION
BEGIN TRY
    UPDATE VendorProducts 
    SET paidPrice = paidPrice * (1 + @perct)
    WHERE vendor = @vendor
END TRY
BEGIN CATCH
   ROLLBACK TRANSACTION
   PRINT 'Error occurred while trying to update vendor products table'
   RETURN -11001
END CATCH

COMMIT TRANSACTION

SELECT * 
FROM VendorProducts
WHERE vendor = @vendor

RETURN 0

1 Ответ

0 голосов
/ 29 апреля 2019

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

ALTER PROCEDURE HW5UD1

Начните сначала.Это имя бесполезно.Любой, кто читает ваш код (или код, который вызывает эту процедуру), должен иметь представление о том, что делает ваша процедура, просто читая это имя.

И давайте посмотрим, как вы вызываете эту процедуру.Сначала вы сказали, что вызываете эту процедуру с помощью "@ vendor = 1".А чуть позже вы говорите: «vendor - это название поставщика, такое как DVDemporium».Здесь что-то кажется неправильным и противоречивым.С точки зрения схемы у вас должен быть внешний ключ (FK) от VendorProducts до Vendors.Вы?У вас даже есть стол продавцов?И столбец FK varchar или числовой?Я ожидал бы числовой, поскольку вы передали значение 1.

Далее ваша процедура содержит один оператор DML.Одно утверждение (в данном случае обновление) является атомарным и будет либо успешным, либо нет.Там нет необходимости для транзакции.Если транзакция была запущена до вызова этой процедуры, вы вложили транзакцию без особой причины.Хуже того, вы ловите любую ошибку, а затем скрываете ИСТИННУЮ ошибку, выбрасывая одну из ваших собственных.Вы только что сделали отладку любых реальных ошибок невозможной с сокрытием.Обработка ошибок сложна в tsql - я предлагаю вам прочитать обсуждение Эрланда .

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

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

Так что, возможно, это все упражнение для обучения.К сожалению, люди склонны предоставлять рабочий код без особых объяснений.Конечно, вы можете просто скопировать это и сдать его для оценки.Но вы не многому научились (если таковые имеются), и это прискорбно.Без понимания и изучения вы не сможете развить навыки, необходимые для того, чтобы стать эффективным разработчиком.

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

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