Подтвердить что ты не робот

Почему блок TRY-CATCH не разрешен внутри UDF?

Почему SQL Server не поддерживает блоки TRY-CATCH внутри UDF?

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

Кроме того, какие обходные пути вы используете для этого?

4b9b3361

Ответ 1

UDF в MSSQL не имеют побочных эффектов, которые BOL определяет как "изменение состояния базы данных". Это довольно неопределенное описание, но MSSQL, по-видимому, рассматривает ошибки для изменения состояния базы данных - этот UDF не компилируется:

create function dbo.foo()
returns int
as
begin
    raiserror('Foo', 16, 1)
    return 1
end
go

Сообщение об ошибке:

Msg 443, уровень 16, состояние 14, процедура foo, строка 5 Недопустимое использование побочный оператор "RAISERROR" внутри функции.

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

В практическом плане, однако, часто бывает лучше, чтобы вызывающий абонент решил, как обращаться с ошибками. Скажем, вы пишете такую ​​функцию:

create function dbo.divide (@x int, @y int)
returns float
as
begin
return @x / cast(@y as float)
end

Как бы вы справлялись с случаем, когда приложение пропускает ноль для @y? Если вы поймаете деление на нулевое исключение, что вы собираетесь делать дальше? Какое значение вы можете вернуть из функции, которая имеет смысл для вызывающего, учитывая, что вы даже не можете узнать, какое приложение вызывает вашу функцию?

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

Если вы единственный разработчик, возможно, это не проблема, но с большим количеством людей он быстро становится одним.

Ответ 2

Как работа, я бы назвал UDF из TRY/CATCH внутри хранимой процедуры.

Ответ 3

Возможно, это связано с тем, что накладные расходы слишком велики - скалярная функция может быть вызвана в столбце как часть f выбора и поэтому будет называться тысячами раз. Если бы были разумные накладные расходы, чтобы позволить try/catch, это ужасно замедляло бы его.