1

私の問題は、配列バインドとしてIDのリストがあるPL/SQL内で動的SQLクエリを実行したいということです。Oracle ドキュメントで、数値のリストを DML ステートメントに結合する方法の例をいくつか見つけました。( http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_sql.htm#i996963 )

今、Select-Statements についても同じことをしようとしています。に Array-Binds を使用できることを知っていexecute immediate-Statementます。しかし、これには、Statement を実行する前に Bind-Variables の正確な数を知らなければならないという欠点があります。これが、dbms_sql を使用しなければならない理由です。

次の例は 1 つの行のみを返しますが、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;
4

1 に答える 1

0

複数の値を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;
于 2014-07-09T08:52:59.380 に答える