Почему не делает Блоков try-catch поддержки SQL Server в UDFs?
Если мы говорим о скалярных UDFs, которые главным образом используются для вычислений и переговоров, этот блок должен в большой степени использоваться, но у нас нет его.
Кроме того, какие обходные решения Вы используете для этого?
UDF в MSSQL не допускают побочных эффектов, которые БОЛ определяет как "изменение состояния базы данных". Это довольно расплывчатое описание, но MSSQL, видимо, учитывает ошибки при изменении состояния базы данных - этот UDF не компилирует:
create function dbo.foo()
returns int
as
begin
raiserror('Foo', 16, 1)
return 1
end
go
Сообщение об ошибке:
Msg 443, Level 16, State 14, Procedure Фу, строка 5 Недействительное использование побочный оператор 'РЕЙЗЕРРОР' Внутри функции
Если считается, что поднятие ошибки приводит к изменению состояния БД, то, предположительно, это также ловушка и обработка одной из них. Что, признаюсь, не является большим объяснением.
На практике, однако, зачастую лучше всего позволить вызывающему абоненту все равно решить, как работать с ошибками. Скажем, вы пишете такую функцию:
create function dbo.divide (@x int, @y int)
returns float
as
begin
return @x / cast(@y as float)
end
Как бы вы справились с ситуацией, когда приложение передает ноль для @y? Если поймать деление на ноль, что делать дальше? Какое значение вы можете вернуть из функции, которая имеет смысл для вызывающего, имея в виду, что вы можете даже не знать, какое приложение вызывает вашу функцию в любом случае?
Вы можете подумать о возвращении NULL, но согласятся ли разработчики приложения, использующие вашу функцию? Считают ли все свои приложения, что разделение на нулевую ошибку имеет одинаковое влияние или значение? Не говоря уже о том, что NULL в некоторых местах могут полностью изменить результаты запроса, возможно, таким образом, что разработчик приложения не захочет этого вообще.
Если вы единственный разработчик, может быть, это и не проблема, но с большим количеством людей это быстро становится проблемой.
.] В качестве работы я бы вызвал UDF из TRY/CATCH внутри хранимой процедуры. [
]Может быть, это из-за того, что накладные расходы слишком велики - скалярная функция может быть вызвана на столбце как часть выборки и так быть вызвана тысячи раз. Если бы были разумные накладные расходы, чтобы позволить попытку/поимку, это бы ужасно замедлило ее.