create or replace
function f_amt(date_in in varchar2) return number
as
BEGIN
DECLARE
v_at ES.AMT%TYPE;
i number := 0;
BEGIN
v_at := 0;
WHILE v_at = 0
LOOP
BEGIN
select nvl(AMT,0)
into v_at
from es
where date1 = to_date(date_in,'MM/DD/YYYY') - i;
i := i + 1;
EXCEPTION when NO_DATA_FOUND
then
v_at:=0;
END;
END LOOP;
RETURN v_at;
END;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
Таблица ES имеет дату и сумму, и я хочу указать как o/p для последней даты, доступной в ES для указанной даты.pl/sql блок, идущий в бесконечной петле
Например: Если дата '20160223' и сумма в ES доступны для '20160220', тогда этот символ должен быть возвращен в v_at и выше, а цикл должен выйти. Но это происходит бесконечно. Пожалуйста, предложите исправление в коде.
Хороший совет не использовать 'WHEN OTHERS', потому что мы также будем проглатывать исключения, когда' date1' переименовывается в 'date2' например и, следовательно, никогда не знает почему функция всегда возвращает 0 внезапно. Однако «КОГДА ДРУГИЕ», очевидно, используются здесь, чтобы поймать все возможные исключения TO_DATE. До тех пор, пока задача функции должна возвращать 0 в недопустимых строках даты, требуется что-то вроде общей обработки исключений. Вот этот вопрос, посвященный именно этому: http://stackoverflow.com/questions/9836508/converting-a-string-to-date-and-raising-an-exception-when-given-string-is-invali –
@ ThorstenKettner Я вижу, но я не думаю, что если вы передадите эту функцию, дату «20160223» и вы ожидаете формат «MM/DD/YYYY», будет хорошей идеей проглотить это исключение. – Mottor
Вы правы; вызывающему абоненту следует сообщить, что указанная строка даты считается недействительной. Это было бы намного лучше. Это сводится к: функция проверяет строку даты и получает AMT в случае, если она действительна. Вместо этого это должны быть две отдельные задачи. –