#plsql #oracle11g #bind-variables
#plsql #oracle11g #привязка-переменные
Вопрос:
Моя проблема в том, что я хочу выполнить динамический SQL-запрос в PL / SQL, где у меня есть список идентификаторов в качестве привязки к массиву. В документации Oracle я нашел несколько примеров того, как присоединять списки чисел к инструкции DML. (http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sql.htm#i996963 )
Теперь я пытаюсь сделать то же самое для операторов Select. Я знаю, что могу использовать привязки массива для execute immediate-Statement
. Но это имеет тот недостаток, что я должен знать точное количество переменных привязки перед выполнением инструкции. Это причина, по которой я должен использовать dbms_sql.
Следующий пример возвращает только одну строку, но он должен возвращать 3 строки. Кто-нибудь знает, в чем проблема с моим примером?
--TestData:
CREATE TABLE PERSON AS
SELECT LEVEL AS ID, 'Person_'||LEVEL AS NAME
FROM DUAL CONNECT BY LEVEL <= 5;
declare
p_ids dbms_sql.number_table;
c number;
dummy NUMBER;
p_name varchar2(100);
begin
p_ids(1) := 2;
p_ids(2) := 3;
p_ids(3) := 4;
--
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, 'select name from PERSON where id in(:num_array)', DBMS_SQL.NATIVE);
dbms_sql.define_column(c, 1, p_name, 100);
DBMS_SQL.BIND_ARRAY(c, ':num_array', p_ids);
dummy := DBMS_SQL.EXECUTE(c);
--
loop
exit when dbms_sql.fetch_rows(c) <=0;
dbms_sql.column_value(c, 1, p_name);
dbms_output.put_line(p_name);
end loop;
DBMS_SQL.CLOSE_CURSOR(c);
end;
Комментарии:
1. Насколько мне известно, Oracle не предоставляет средства для привязки массива к
IN
списку значений. Желаю удачи.
Ответ №1:
Вот мое текущее решение для привязки нескольких значений к инструкции Select, возможно, кому-то это может понадобиться:
--TestData:
CREATE TABLE PERSON AS
SELECT LEVEL AS ID, 'Person_'||LEVEL AS NAME
FROM DUAL CONNECT BY LEVEL <= 5;
declare
c number;
dummy NUMBER;
p_name varchar2(100);
xml$ varchar2(1000);
begin
--Generate a XML-List instead of dbms_sql.number_table:
xml$ := '<ids><id>2</id><id>3</id><id>4</id></ids>';
--
c := dbms_sql.open_cursor;
--Using XML-Functions for extracting the Values from the XML-String
DBMS_SQL.PARSE(c, 'select name
from PERSON
where id in(select extractvalue(value(x), ''id'')
from table(xmlsequence(xmltype(:ids).extract(''ids/*'')))x)'
, DBMS_SQL.NATIVE);
dbms_sql.define_column(c, 1, p_name, 100);
DBMS_SQL.BIND_variable(c, ':ids', xml$);
dummy := DBMS_SQL.EXECUTE(c);
--
loop
exit when dbms_sql.fetch_rows(c) <=0;
dbms_sql.column_value(c, 1, p_name);
dbms_output.put_line(p_name);
end loop;
DBMS_SQL.CLOSE_CURSOR(c);
end;