需要使用包常量下定义的对象类型进行动态查询

时间:2017-11-22 15:53:55

标签: xml oracle plsql

   CREATE OR REPLACE TYPE TYPE_T
    AS
       OBJECT (
              REQUEST_ID                        NUMBER(10),
              CALL_TYPE                         VARCHAR2(30),
              RESPONSE_CODE                     VARCHAR2(20)
              );
    /

下面的块是通过使用USING子句

执行动态查询来工作的
declare
 l_sql    VARCHAR2(2000);
 l_test_t test_t := test_t();
 l_to_xml   xmltype;
begin
 l_test_t.REQUEST_ID := 10;
 l_test_t.CALL_TYPE := 'CALL_TYPE';
 l_sql := 'SELECT XMLFOREST (:p_ior_order_t as order_details) FROM dual' ;
 EXECUTE IMMEDIATE l_sql INTO l_to_xml using l_test_t ;
 DBMS_OUTPUT.put_line(l_to_xml.getstringval);
end;

- 输出:

<ORDER_DETAILS><REQUEST_ID>10</REQUEST_ID><CALL_TYPE>CALL_TYPE</CALL_TYPE></ORDER_DETAILS>

现在在下面的块中假设我们将通过包常量获取对象名称,该常量将作为过程的输入接收。

create or replace PACKAGE test_package
AS
pv_test_t  TYPE_T:= TYPE_T(); 
end;

以下方式调用dynamic_xmltype(&#39; test_package.pv_test_t&#39;);

procedure dynamic_xmltype (p_name  VARCHAR2)
AS
begin
     l_sql    VARCHAR2(2000);
     l_test_t test_t := test_t();
     l_to_xml   xmltype;
    begin
     l_test_t.REQUEST_ID := 10;
     l_test_t.CALL_TYPE := 'CALL_TYPE';
     l_sql := 'SELECT XMLTYPE ( '|| p_name|| ') FROM dual' ;
     EXECUTE IMMEDIATE l_sql INTO l_to_xml ;
     DBMS_OUTPUT.put_line(l_to_xml.getstringval);
    end;

ORA-06550: line 8, column 11:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 8, column 2:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

你能帮助别人帮忙吗?

1 个答案:

答案 0 :(得分:1)

我没有看到您使用动态SQL的任何原因,它在没有任何动态SQL的情况下工作:

CREATE OR REPLACE TYPE TYPE_T AS OBJECT (
    REQUEST_ID    NUMBER(10),
    CALL_TYPE     VARCHAR2(30),
    RESPONSE_CODE VARCHAR2(20));
/

CREATE OR REPLACE PACKAGE test_package AS
    pv_test_t TYPE_T:= TYPE_T(20,'CALL_TYPE',NULL); 
END;

DECLARE
    l_test_t TYPE_T := TYPE_T(10,'CALL_TYPE',NULL);
    l_to_xml   XMLTYPE;
BEGIN
    SELECT XMLFOREST(l_test_t AS order_details) INTO l_to_xml FROM DUAL;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);

    l_to_xml := XMLTYPE(l_test_t);
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);
end;


DECLARE
    l_to_xml   XMLTYPE; 
BEGIN    
    SELECT XMLFOREST(test_package.pv_test_t AS order_details) INTO l_to_xml FROM dual;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);    

    l_to_xml := XMLTYPE(test_package.pv_test_t);
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);    
END;

无论如何,如果您因任何原因必须使用动态SQL,它将成为这些解决方案之一:

DECLARE
    l_to_xml   XMLTYPE; 
    l_test_t TYPE_T := TYPE_T(10,'CALL_TYPE',NULL);
BEGIN    
    EXECUTE IMMEDIATE 'SELECT XMLFOREST(:p AS order_details) FROM dual' INTO l_to_xml USING l_test_t;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval); 

    EXECUTE IMMEDIATE 'SELECT XMLTYPE(:p) FROM dual' INTO l_to_xml USING l_test_t;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);     
END;


DECLARE
    l_to_xml   XMLTYPE;         
    p_test_t TYPE_T;
    p_name VARCHAR2(1000) := 'test_package.pv_test_t';      
BEGIN

    EXECUTE IMMEDIATE 'BEGIN :res := '||p_name||'; END;' USING OUT p_test_t;

    SELECT XMLFOREST(p_test_t AS order_details) INTO l_to_xml FROM dual;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);

    l_to_xml := XMLTYPE(p_test_t);
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);

    EXECUTE IMMEDIATE 'SELECT XMLFOREST(:p AS order_details) FROM dual' INTO l_to_xml USING p_test_t;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval); 

    EXECUTE IMMEDIATE 'SELECT XMLTYPE(:p) FROM dual' INTO l_to_xml USING p_test_t;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);        

    EXECUTE IMMEDIATE 'BEGIN :res := XMLTYPE('||p_name||'); END;' USING OUT l_to_xml;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);

    EXECUTE IMMEDIATE 'BEGIN SELECT XMLFOREST('||p_name||' AS order_details) INTO :res FROM dual; END; ' USING OUT l_to_xml;
    DBMS_OUTPUT.PUT_LINE(l_to_xml.getstringval);

END;