и здесь фантастический способ (неэффективен):)
byte[] b = { 48, 48, 49, 48, 48, 52 };
ByteArrayInputStream bais = new ByteArrayInputStream(b);
BufferedReader buf = new BufferedReader(new InputStreamReader(bais));
String s = buf.readLine();
System.out.println(s);
RAISEERROR
или @@ ERROR
не допускаются в UDF. Можно ли превратить UDF в структурированную процедуру?
Из статьи Эрланда Соммарскога Обработка ошибок в SQL Server - фон :
Пользовательские функции обычно вызывается как часть SET, SELECT, Оператор INSERT, UPDATE или DELETE. Я обнаружил, что если ошибка появляется в мульти-заявлении функция с табличным значением или в скаляре функция, выполнение функция немедленно прерывается, и так это утверждение, что функция часть. Исполнение продолжается на следующая строка, если ошибка не устранена партия. В любом случае ошибка @@ 0. Таким образом, невозможно обнаружить ошибку в функции. из T-SQL.
Проблема не возникает с встроенные табличные функции, поскольку встроенная функция с табличным значением в основном макрос, который запрос процессор вставляет в запрос.
Вы также можете выполнять скалярные функции с заявлением EXEC. В этом случае, выполнение продолжается, если возникает ошибка (если это не ошибка прерывания партии). @@ установлена ошибка, и вы можете проверить значение @@ ошибка в функции. Может быть проблематично общаться однако ошибка вызывающего абонента.
Обычный трюк - принудительное деление на 0. Это вызовет ошибку и прервет текущий оператор, оценивающий функцию. Если разработчик или сотрудник службы поддержки знают об этом поведении, исследовать и устранить проблему довольно просто, поскольку ошибка деления на 0 понимается как симптом другой, не связанной с этим проблемы.
Как бы плохо это ни выглядело с любой точки зрения, к сожалению, дизайн функций SQL в настоящий момент не позволяет сделать лучшего выбора. Использование RAISERROR должно быть абсолютно разрешено в функциях.
Один из способов (взлом) - иметь функцию / хранимую процедуру, которая выполняет недопустимое действие. Например, следующий псевдо-SQL
create procedure throw_error ( in err_msg varchar(255))
begin
insert into tbl_throw_error (id, msg) values (null, err_msg);
insert into tbl_throw_error (id, msg) values (null, err_msg);
end;
Где в таблице tbl_throw_error есть уникальное ограничение на столбец err_msg.
Я думаю, что самый чистый способ - это просто принять, что функция может вернуть NULL, если передаются недействительные аргументы. До тех пор, пока это явно документировано, это должно быть нормально?
-- =============================================
-- Author: AM
-- Create date: 03/02/2010
-- Description: Returns the appropriate exchange rate
-- based on the input parameters.
-- If the rate cannot be found, returns NULL
-- (RAISEERROR can't be used in UDFs)
-- =============================================
ALTER FUNCTION [dbo].[GetExchangeRate]
(
@CurrencyFrom char(3),
@CurrencyTo char(3),
@OnDate date
)
RETURNS decimal(18,4)
AS
BEGIN
DECLARE @ClosingRate as decimal(18,4)
SELECT TOP 1
@ClosingRate=ClosingRate
FROM
[FactCurrencyRate]
WHERE
FromCurrencyCode=@CurrencyFrom AND
ToCurrencyCode=@CurrencyTo AND
DateID=dbo.DateToIntegerKey(@OnDate)
RETURN @ClosingRate
END
GO