Я пишу пользовательскую функцию в SQL Server 2008. Я знаю, что функции не могут вызывать ошибки обычным способом - если вы попытаетесь включить инструкцию RAISERROR, SQL возвращает:
Msg 443, Level 16, State 14, Procedure ..., Line ...
Invalid use of a side-effecting operator 'RAISERROR' within a function.
Но дело в том, что функция принимает некоторый ввод, который может быть недействительным, и, если это так, нет значимого значения, которое функция может вернуть. Что мне тогда делать?
Я мог бы, конечно, вернуть NULL, но для любого разработчика было бы сложно устранить эту проблему. Я также мог бы вызвать деление на ноль или что-то в этом роде - это сгенерировало бы сообщение об ошибке, но вводящее в заблуждение Могу ли я каким-либо образом сообщать о своем сообщении об ошибке?
declare @error int; set @error = 'Error happened here.';
Обычный трюк - форсировать деление на 0. Это вызовет ошибку и прервет текущий оператор, который оценивает функцию. Если разработчик или специалист службы поддержки знают об этом поведении, расследование и устранение неполадок достаточно просто, поскольку ошибка деления на 0 понимается как признак другой, не связанной проблемы.
Как бы плохо это ни выглядело с любой точки зрения, к сожалению, дизайн функций SQL на данный момент не дает лучшего выбора. Использование RAISERROR должно быть абсолютно разрешено в функциях.
источник
Исходя из ответа Владимира Королева, условно выдать ошибку
источник
Я думаю, что самый простой способ - просто принять, что функция может возвращать NULL, если переданы недопустимые аргументы. Пока это четко задокументировано, тогда это должно быть хорошо?
источник
RAISEERROR
или@@ERROR
не допускаются в UDF. Можете ли вы превратить UDF в пошаговую процедуру?Из статьи Эрланда Соммарского, Обработка ошибок в SQL Server - фон :
источник
Верхний ответ обычно лучший, но он не работает для встроенных табличных функций.
MikeTeeVee дал решение для этого в своем комментарии к верхнему ответу, но для этого требовалось использовать агрегатную функцию, такую как MAX, которая не работала в моих обстоятельствах.
Я возился с альтернативным решением для случая, когда вам нужна встроенная таблица со значением udf, которая возвращает что-то вроде select * вместо агрегата. Пример кода, решающего этот конкретный случай, приведен ниже. Как кто-то уже указал ... "JEEZ wotta hack" :) Я приветствую любое лучшее решение для этого случая!
источник
Несколько человек спрашивали о возникновении ошибок в табличных функциях, так как вы не можете использовать вещи типа « RETURN [invalid cast] ». Присвоение неверного приведения переменной также работает.
Это приводит к:
источник
Я не могу комментировать ответ davec относительно табличной функции, но по моему скромному мнению это более простое решение:
источник
Один из способов (взлом) - иметь функцию / хранимую процедуру, которая выполняет недопустимое действие. Например, следующий псевдо SQL
В таблице tbl_throw_error существует уникальное ограничение для столбца err_msg. Побочным эффектом этого (по крайней мере для MySQL) является то, что значение err_msg используется в качестве описания исключения, когда оно возвращается в объект исключения уровня приложения.
Я не знаю, можно ли сделать что-то подобное с SQL Server, но стоит попробовать.
источник