Есть какая-то особая причина для Dynami c SQL? В выполняемых вами запросах нет ничего Dynami c.
Что хуже , так это то, что эти выборки используют UNION
, что означает, что они, возможно, вернут две или более строк в скалярную переменную, и это не сработает.
Кроме того, вы неправильно использовали предложение INTO
.
Это похоже на то, что вы делаете сейчас (пример основан на схеме Скотта):
SQL> declare
2 l_result varchar2(20);
3 begin
4 execute immediate
5 q'[select deptno into :out1
6 from emp
7 where ename = 'SCOTT'
8 union
9 select deptno into :out2
10 from dept
11 where dname = 'ACCOUNTING']'
12 using out l_result;
13
14 dbms_output.put_line(l_result);
15 end;
16 /
declare
*
ERROR at line 1:
ORA-01744: inappropriate INTO
ORA-06512: at line 4
SQL>
Если вы исправите это, вы получите хуже вещь: too_many_rows
, поскольку вы возвращаете 2 строки в одну varchar2
переменную:
SQL> declare
2 l_result varchar2(20);
3 begin
4 execute immediate
5 q'[select deptno
6 from emp
7 where ename = 'SCOTT'
8 union
9 select deptno
10 from dept
11 where dname = 'ACCOUNTING']'
12 into l_result;
13
14 dbms_output.put_line(l_result);
15 end;
16 /
declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4
Поскольку в нем нет ничего динамического c , переключитесь на чистый select
(конечно, снова вернет too_many_rows
):
SQL> declare
2 l_result varchar2(20);
3 begin
4 select deptno
5 into l_result
6 from (select deptno
7 from emp
8 where ename = 'SCOTT'
9 union
10 select deptno
11 from dept
12 where dname = 'ACCOUNTING'
13 );
14
15 dbms_output.put_line(l_result);
16 end;
17 /
declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 4
Наконец, используйте соответствующую переменную, массив:
SQL> declare
2 l_result sys.odcivarchar2list;
3 begin
4 select deptno
5 bulk collect into l_result
6 from (select deptno
7 from emp
8 where ename = 'SCOTT'
9 union
10 select deptno
11 from dept
12 where dname = 'ACCOUNTING'
13 );
14
15 for i in l_result.first .. l_result.last loop
16 dbms_output.put_line(l_result(i));
17 end loop;
18 end;
19 /
10
20
PL/SQL procedure successfully completed.
SQL>
As ошибок, с которыми вы сталкиваетесь: как вам уже было сказано, вам нужно заключить каждый оператор в отдельный блок begin-exception-end. Что-то вроде этого упрощенного примера («упрощенный» означает, что вы должны правильно обрабатывать исключения. Не используйте WHEN OTHERS только потому, что они существуют; вы бы предпочли позволить ошибке произойти, распознать ее и обработать правильно):
declare
l_result sys.odcivarchar2list;
begin
-- start of the first inner begin-exception-end block
begin
select deptno
bulk collect into l_result
from (select deptno
from emp
where ename = 'SCOTT'
union
select deptno
from dept
where dname = 'ACCOUNTING'
);
for i in l_result.first .. l_result.last loop
dbms_output.put_line(l_result(i));
end loop;
exception
when others then
dbms_output.put_Line('handle it');
end;
-- end of the first inner begin-exception-end block
-- start of the second inner begin-exception-end block
begin
null;
exception
when others then null;
end;
-- end of the second inner begin-exception-end block
end;
/