【问题标题】:PLSQL : How to save a dynamic SQL query result into a two dimension array?PLSQL:如何将动态 SQL 查询结果保存到二维数组中?
【发布时间】:2012-10-08 01:36:38
【问题描述】:
CREATE TYPE VarArray AS VARRAY(50) OF VARCHAR2(50);

CREATE TYPE VarAArray AS VARRAY(50) OF VarArray;

Declare
   myTable VarAArray VarAArray();
   tableName Varchar2(50);
Begin
  -- I want to save the data in the table of 'tableName' 
  -- into the myTable array, all the field values are 
  -- saved as varchar2 type
End;

这样做的关键要求是通过行号和列 id 获取任何字段值。请随时提供更好的设计方案。

【问题讨论】:

  • 我想将所有表值存储到格式良好的 XML 文件中 FieldValue ... .. ...
  • Oracle 中已经有大量的 XML 函数可用,为什么不使用它们呢?如果 XML 函数不是一个选项,那么 EXECUTE IMMEDIATE 'SELECT * BULK COLLECT INTO myTable FROM table_name'; 应该完成填充集合的工作。

标签: sql arrays oracle dynamic plsql


【解决方案1】:

如果您想获得表中数据的 XML 表示,请查看 dbms_xmlgen 包。例如,您可以编写一个像这样的简单函数:

SQL> create or replace function GenXML(p_query in varchar2, p_RSetTag in varchar2)
  2  return clob
  3  is
  4    l_xmlcntx dbms_xmlgen.ctxHandle;
  5    l_resxml clob;
  6  begin
  7    l_xmlcntx := dbms_xmlgen.newContext(p_query);
  8    dbms_xmlgen.setRowSetTag(l_xmlcntx,  p_RSetTag);
  9    l_resxml := dbms_xmlgen.getXML(l_xmlcntx);
 10    dbms_xmlgen.closeContext(l_xmlcntx);
 11    return l_resxml;
 12  end;
 13  /

Function created

然后通过将查询传递给表和行集标记作为参数,按如下方式使用它。

SQL> select genxml('select * from employees where rownum = 1','EMPLOYEES') as XmlData
  2    from dual
  3  ;

XMLDATA
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<EMPLOYEES>
 <ROW>
  <EMPLOYEE_ID>100</EMPLOYEE_ID>
  <FIRST_NAME>100</FIRST_NAME>
  <LAST_NAME>King</LAST_NAME>
  <EMAIL>SKING</EMAIL>
  <PHONE_NUMBER>515.123.4567</PHONE_NUMBER>
  <HIRE_DATE>17-JUN-03</HIRE_DATE>
  <JOB_ID>AD_PRES</JOB_ID>
  <SALARY>24000</SALARY>
  <DEPARTMENT_ID>90</DEPARTMENT_ID>
 </ROW>
</EMPLOYEES>

SQL> 

回复评论

要显示主从类型的数据结构,您可以使用cursor。例如:

SQL> select genxml('select department_id
  2       , department_name
  3       , cursor(
  4                 select first_name
  5                   from employees t
  6                  where t.department_id = d.department_id
  7           ) employees
  8    from departments d
  9    where rownum = 1','DEPARTMENTS') xmldata
 10    from dual
 11  ;

XMLDATA
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<DEPARTMENTS>
 <ROW>
  <DEPARTMENT_ID>10</DEPARTMENT_ID>
  <DEPARTMENT_NAME>Administration</DEPARTMENT_NAME>
  <EMPLOYEES>
   <EMPLOYEES_ROW>
    <FIRST_NAME>Jennifer</FIRST_NAME>
   </EMPLOYEES_ROW>
  </EMPLOYEES>
 </ROW>
</DEPARTMENTS>

UPDATE #2 回复评论:

为了在“detail”(光标)为空的情况下消除剩余的开始和结束标签,让我们重写我们的查询如下,例如:

SELECT XMLElement("DEPARTMENTS"
                 , XMLAgg( XMLElement( "ROW"
                                     , XMLForest( t.department_id
                                                , t.department_name
                                                )
                                     , (
                                         SELECT XMLAgg(XMLElement("EMPLOYEES"
                                                                 , XMLForest (q.first_name)
                                                                  )
                                                        )
                                           FROM employees q
                                          WHERE q.department_id = t.department_id
                                            --and 100=101
                                        )
                                     )
                          )
                 )

为了更好地控制标签。并将上述查询的结果存储在文件中,如下所示: 在运行以下代码之前,必须创建一个目录:Create directory &lt;name&gt; as &lt;path&gt;。如果您的目录而不是XMLDIR,请输入名称。

declare
  l_xml clob;

begin
  SELECT XMLElement("DEPARTMENTS"
                 , XMLAgg( XMLElement( "ROW"
                                     , XMLForest( t.department_id
                                                , t.department_name
                                                )
                                     , (
                                         SELECT XMLAgg(XMLElement("EMPLOYEES"
                                                                 , XMLForest (q.first_name)
                                                                  )
                                                        )
                                           FROM employees q
                                          WHERE q.department_id = t.department_id
                                            --and 100=101
                                        )
                                     )
                          )
                 ).getclobval() into l_xml
  FROM departments t
  where rownum < 3;

  dbms_xslprocessor.clob2file(l_xml, 'XMLDIR', 'XmlFile.xml');

end;

Result#1:当子查询返回数据时

 <DEPARTMENTS>
  <ROW>
    <DEPARTMENT_ID>10</DEPARTMENT_ID> 
    <DEPARTMENT_NAME>Administration</DEPARTMENT_NAME> 
    <EMPLOYEES>
      <FIRST_NAME>Jennifer</FIRST_NAME> 
    </EMPLOYEES>
  </ROW>
  <ROW>
    <DEPARTMENT_ID>20</DEPARTMENT_ID> 
    <DEPARTMENT_NAME>Marketing</DEPARTMENT_NAME> 
    <EMPLOYEES>
      <FIRST_NAME>Michael</FIRST_NAME> 
    </EMPLOYEES>
    <EMPLOYEES>
      <FIRST_NAME>Pat</FIRST_NAME> 
    </EMPLOYEES>
  </ROW>
 </DEPARTMENTS>

结果#2:当子查询没有返回数据时

<DEPARTMENTS>
  <ROW>
    <DEPARTMENT_ID>10</DEPARTMENT_ID> 
    <DEPARTMENT_NAME>Administration</DEPARTMENT_NAME> 
  </ROW>
  <ROW>
    <DEPARTMENT_ID>20</DEPARTMENT_ID> 
    <DEPARTMENT_NAME>Marketing</DEPARTMENT_NAME> 
  </ROW>
  </DEPARTMENTS>

【讨论】:

  • 如果我想在 90 之后附加另一个由 Employee_id 引用的名为employeeDetails 的表,结构相同怎么办?
  • 要了解更多信息,请查看this
  • 还有一个问题,如果光标部分返回null,还是会有这样的标签,你知道怎么避免吗?谢谢@Nicholas
  • @Frank 应该有开始和结束标签&lt;EMPLOYEES&gt;&lt;EMPLOYEES/&gt;
  • 所以如果我不希望 输出,可以吗?谢谢@Nicholas
猜你喜欢
  • 2014-05-06
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
相关资源
最近更新 更多