Oracle:游标在游标内时选择distinct不起作用(使用游标表达式)

时间:2015-02-03 11:47:24

标签: sql oracle cursor expression distinct

我需要制作一份包含一些人及其发票清单的报告;由于我正在生成一些XML(XML发布者),因此一种方法是使用游标表达式。 SQL请求包含一个给出联系人列表的第一个游标,第一个游标列出每个联系人的发票。 问题是联系人SQL请求多次返回同一个联系人(实际上他有多少发票) 所以我需要使用distinct,它不起作用!

为了获得可重现性目的无处不在的请求,我将使用基于oracle系统表all_table和dual的sql请求;

再现联系人列表的SQL请求:

select 
    'ALBERT EINSTEIN' CONTACT_NAME 
  from 
  ALL_VIEWS
  where view_name IN ( 'ALL_INDEXES', 'ALL_TABLES') ;

=> 艾尔伯特爱因斯坦 ALBERT EINSTEIN

SQL请求再现连接到联系人的(1)发票列表:

SELECT 123456 INVOICE_NUMBER, 10000 INVOICE_AMOUNT, 'EUR' INVOICE_CURRENCY FROM DUAL  ;

=>

123456 10000 EUR

因此,使用游标表达式的报告的SQL是:

select distinct
cursor (
  select 
    distinct 
    'ALBERT EINSTEIN' CONTACT_NAME 
    ,CURSOR (SELECT 123456 INVOICE_NUMBER, 10000 INVOICE_AMOUNT, 'EUR' INVOICE_CURRENCY FROM DUAL ) AS INVOICES
  from 
  ALL_VIEWS
  where view_name IN ( 'ALL_INDEXES', 'ALL_TABLES')
  ) AS CONTACTS
  from dual ;

所以要生成XML:

select dbms_xmlgen.getxml('
select distinct
cursor (
  select 
    distinct 
    ''ALBERT EINSTEIN'' CONTACT_NAME 
    ,CURSOR (SELECT 123456 INVOICE_NUMBER, 10000 INVOICE_AMOUNT, ''EUR'' INVOICE_CURRENCY FROM DUAL ) AS INVOICES
  from 
  ALL_VIEWS
  where view_name IN ( ''ALL_INDEXES'', ''ALL_TABLES'')
  ) AS CONTACTS
  from dual 
 ') from dual
;

即:

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <CONTACTS>
   <CONTACTS_ROW>
    <CONTACT_NAME>ALBERT EINSTEIN</CONTACT_NAME>
    <INVOICES>
     <INVOICES_ROW>
      <INVOICE_NUMBER>123456</INVOICE_NUMBER>
      <INVOICE_AMOUNT>10000</INVOICE_AMOUNT>
      <INVOICE_CURRENCY>EUR</INVOICE_CURRENCY>
     </INVOICES_ROW>
    </INVOICES>
   </CONTACTS_ROW>
   <CONTACTS_ROW>
    <CONTACT_NAME>ALBERT EINSTEIN</CONTACT_NAME>
    <INVOICES>
     <INVOICES_ROW>
      <INVOICE_NUMBER>123456</INVOICE_NUMBER>
      <INVOICE_AMOUNT>10000</INVOICE_AMOUNT>
      <INVOICE_CURRENCY>EUR</INVOICE_CURRENCY>
     </INVOICES_ROW>
    </INVOICES>
   </CONTACTS_ROW>
  </CONTACTS>
 </ROW>
</ROWSET>

=&GT;显示两次与同一发票相同的联系,这是无用的,并且由于使用了不同的预期,因此不会发生。

通过评论第二个游标,所有不同的作品:

select dbms_xmlgen.getxml('
select distinct
cursor (
  select 
    distinct 
    ''ALBERT EINSTEIN'' CONTACT_NAME 
    --,CURSOR (SELECT 123456 INVOICE_NUMBER, 10000 INVOICE_AMOUNT, ''EUR'' INVOICE_CURRENCY FROM DUAL ) AS INVOICES
  from 
  ALL_VIEWS
  where view_name IN ( ''ALL_INDEXES'', ''ALL_TABLES'')
  ) AS CONTACTS
  from dual 
 ') from dual
;

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <CONTACTS>
   <CONTACTS_ROW>
    <CONTACT_NAME>ALBERT EINSTEIN</CONTACT_NAME>
   </CONTACTS_ROW>
  </CONTACTS>
 </ROW>
</ROWSET>

因此,当光标内只有游标时会出现问题。

有些人有解决方法吗?

2 个答案:

答案 0 :(得分:0)

我认为你需要不同的输出,如下所示

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <CONTACTS>
   <CONTACTS_ROW>
    <CONTACT_NAME>ALBERT EINSTEIN</CONTACT_NAME>
    <INVOICE_NUMBER>123456</INVOICE_NUMBER>
    <INVOICE_AMOUNT>10000</INVOICE_AMOUNT>
    <INVOICE_CURRENCY>EUR</INVOICE_CURRENCY>
   </CONTACTS_ROW>
  </CONTACTS>
 </ROW>
</ROWSET>

为此,不需要第二个游标。你可以像下面那样实现

select dbms_xmlgen.getxml('
select 
cursor (
  select 
    distinct 
    ''ALBERT EINSTEIN'' CONTACT_NAME 
    , 123456 INVOICE_NUMBER, 10000 INVOICE_AMOUNT, ''EUR'' INVOICE_CURRENCY 
  from 
  ALL_VIEWS
  where view_name IN ( ''ALL_INDEXES'', ''ALL_TABLES'')
  ) AS CONTACTS
  from dual 
 ') from dual
;

因为distint在这种情况下是不同的。因此不需要子光标。这里distinct将自动删除子查询中的所有记录。

答案 1 :(得分:0)

我也得到了相同的情况,过了一段时间我意识到如果我在ORDER BY使用 clause sub cursor那么它就不会给出<强> DISTINCT 值。 使用 sub cursor 而不添加 ORDER BY clause。它肯定会提供 DISTINCT