powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Обработка NO_DATA_FOUND в PL/SQL
7 сообщений из 7, страница 1 из 1
Обработка NO_DATA_FOUND в PL/SQL
    #36495587
kasyanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго времени суток!
Обнаружил, что неправильно обрабатываю пустой результат select into в своих процедурах.
Набросал тестовый пример, чтобы показать, что именно хочу спросить.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
set current schema REPL;
create table TEST (ID INT, NAME VARCHAR( 32 ));
INSERT INTO TEST VALUES ( 1 ,'Test');


CREATE OR REPLACE PROCEDURE REPL.SP_TEST (inputid int)
AS
v_name varchar( 32 );
BEGIN
				select NAME INTO v_name from REPL.TEST where id = inputid;
				if (value(v_name,' ')=' ') then 
					select 'Default' into v_name from dual;				
				end if;
				DBMS_OUTPUT.PUT_LINE(v_name); 
END;
/

set SERVEROUTPUT on
call REPL.SP_TEST(1);
------------------------
Test
DB250000I: Команда выполнена успешно.

call REPL.SP_TEST(2);

SQL0438N Программа генерирует ошибку или предупреждение с текстом диагностики:
"NO_DATA_FOUND".



Подскажите, как правильно переписать код, чтобы обрабатывать такую ситуацию?


Алексей.
...
Рейтинг: 0 / 0
Обработка NO_DATA_FOUND в PL/SQL
    #36495606
kasyanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно отказаться от использования select into в пользу выборки первой записи курсора, но это наворачивает код и делает его менее читабельным. Например,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE OR REPLACE PROCEDURE REPL.SP_TEST (inputid int)
AS
v_name varchar( 32 );
emp_refcur      SYS_REFCURSOR;
BEGIN
				OPEN emp_refcur FOR 'select NAME from REPL.TEST where id = :inputid' USING inputid;
				FETCH emp_refcur INTO v_name;
				if emp_refcur%NOTFOUND then 
					v_name := 'Default';				
				end if;
				DBMS_OUTPUT.PUT_LINE(v_name); 
				CLOSE emp_refcur;
END;
/

SQL> call REPL.SP_TEST(2);
Default
DB250000I: Команда выполнена успешно.
SQL> call REPL.SP_TEST(1);
Test
DB250000I: Команда выполнена успешно.

Может можно как-то проще?
...
Рейтинг: 0 / 0
Обработка NO_DATA_FOUND в PL/SQL
    #36496381
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE OR REPLACE PROCEDURE TEST_PLSQL (inputid int)
AS
v_name varchar( 32 );
BEGIN
 begin			
 select NAME INTO v_name from TEST_PLSQL where id = inputid; 
 EXCEPTION
   WHEN NO_DATA_FOUND THEN NULL;
 end;
 if (value(v_name,' ')=' ') then 
  select 'Default' into v_name from dual;				
 end if;
 DBMS_OUTPUT.PUT_LINE(v_name); 
END;
/
...
Рейтинг: 0 / 0
Обработка NO_DATA_FOUND в PL/SQL
    #36517512
Фотография Anton Demidov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подправлю немного
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE OR REPLACE PROCEDURE TEST_PLSQL (inputid int)
AS
    v_name VARCHAR( 32 );
BEGIN
    BEGIN			
        SELECT name INTO v_name FROM test_plsql WHERE id = inputid; 
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
             v_name := 'Default';
    END;
    DBMS_OUTPUT.PUT_LINE(v_name); 
END;
/
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Обработка NO_DATA_FOUND в PL/SQL
    #39992687
your_frend
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот пытаюсь в строке сделать изменение, если нет строки с параметром, то создаю c нужными данными:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
cursor x is
   select idstr from str where idstr in(значания);
for rx in x loop
   if x%NOTFOUND then
       insert unto str  ..... ;
       RETURNING idstr
      into pidstr;
  else update idstr set ...;
end loop;




вылетает при первом пустом значении ;
Как сделать так чтобы не вылетал из цикла ?
...
Рейтинг: 0 / 0
Обработка NO_DATA_FOUND в PL/SQL
    #39992892
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используйте MERGE .

Вообще, использовать процедурную логику (итерировать вручную по result set'у) - это крайне порочная практика. Есть исключения (когда, например, надо раздробить слишком большую транзакцию), но лучше оперировать data set'ами непосредственно в SQL.
Это и компактней/более читаемо/проще модифицируемо, и выполнит СУБД это как правило быстрее, и поддерживать проще (особенно в долгосрочной перспективе, когда статистические характеристики данных и, соответственно, оптимальный алгоритм/план доступа к данным могут поменяться, а разработчика уже не найти).

Если же очень надо использовать обработку not found логики, то это делается через CONDITION'ы и HANDLER'ы. Вот как вот здесь.
...
Рейтинг: 0 / 0
Обработка NO_DATA_FOUND в PL/SQL
    #39992935
CawaSPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот, кстати, и Том Кайт со мной согласен (:)) (для всех реляционных СУБД это справедливо):
https://asktom.oracle.com/Misc/slow-by-slow.html

На ту же тему:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1205168148688
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:73891904732164 .
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Обработка NO_DATA_FOUND в PL/SQL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]