Я оказался в ситуации, когда мой код должен выполнить динамический оператор, образованный неизвестным числом (по крайней мере, одним, но может быть и больше) других динамических операторов, объединенных операторами «пересечение» и «объединение».
Вот пример с тремя запросами (я знаю, что это можно решить с помощью одного запроса, я стараюсь не усложнять):
sql1 varchar2(500) := 'select empno from emp where deptno = :1';
sql2 varchar2(500) := 'select empno from emp where sal > :2 and hiredate >=:3';
sql3 varchar2(500) := 'select empno from emp where sal <= :2 and hiredate =:3'
realStatement varchar(1500) := sql1 || ' insersect ' || sql2 || ' union ' sql3;
Теперь, учитывая, что количество подоператоров неизвестно во время выполнения, но известны значения всех переменных привязки (т. е. deptno, sal и Hiredate всегда будут: 1, : 2 и : 3 соответственно). Я не могу использовать форму 'EXECUTE IMMEDIATE realStatement USING', потому что ее привязки являются позиционными, и для этого примера я должен передать параметры sal и Hiredate дважды, что приведет к утверждению:
EXECUTE IMMEDIATE realStatement USING l_deptno,l_sal,l_hiredate,l_sal,l_hiredate;
О чем я никак не мог знать заранее, чтобы включить все повторения для каждого подутверждения.
Я знаю, что я мог бы использовать пакет DBMS_SQL с функцией bind(), но производительность в 1,5-3 раза хуже, чем с собственной динамикой (из документации оракула), и в этом случае производительность актуальна.
Итак, что я на самом деле делаю, так это заменяю все вхождения ':1' на l_deptno, все вхождения ':2' на l_sal и все вхождения ':3' на 'to_date(''' || l_hiredate || '' ',''ДД/ММ/ГГГГ'')' в строке realStatement перед выполнением следующим образом:
realStatement := replace(realStatement,':1',l_deptno);
realStatement := replace(realStatement,':2',l_sal);
realStatement := replace(realStatement,':3','to_date(''' || l_hiredate || ''',''DD/MM/YYYY'')');
EXECUTE IMMEDIATE realStatement;
Но я не уверен, что это лучшее решение, вопросы:
Есть ли способ повысить производительность или динамически передавать привязки с помощью собственного динамического SQL?
приведет ли использование пакета DBSM_SQL к повышению производительности по сравнению с выбранным решением?
sql1 varchar2(500) := 'select empno from emp where deptno = ' || :1
вашу потребность? - person Politank-Z   schedule 24.04.2015