Почему БЛОК TRY-CATCH не позволяется в UDFs?

Почему не делает Блоков try-catch поддержки SQL Server в UDFs?

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

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

23
задан Fedor Hajdu 8 August 2012 в 12:31
поделиться

3 ответа

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 в некоторых местах могут полностью изменить результаты запроса, возможно, таким образом, что разработчик приложения не захочет этого вообще.

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

.
13
ответ дан 29 November 2019 в 03:04
поделиться
[

] В качестве работы я бы вызвал UDF из TRY/CATCH внутри хранимой процедуры. [

]
2
ответ дан 29 November 2019 в 03:04
поделиться

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

2
ответ дан 29 November 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: