生成XML数据时计算行

时间:2016-05-26 08:16:35

标签: sql xml oracle

我正在生成XML。我需要创建某种序列。像rownum或row_number()的东西。

   select XMLROOT ( xmlagg(
                       xmlelement(
                         "table_description", 
                          xmlelement(
                            "table_name",
                            max(table_name)
                          ),
                          xmlelement(
                            "table_sequence"
                          ),
                          xmlelement(
                            "table_columns",
                            xmlagg(
                              xmlforest(
                              column_name as "column_name",
                              '' as "column_sequence"
                              )
                            )
                          )
                      )
                ), VERSION '1.0', STANDALONE YES) 
    from all_tab_columns 
    where owner='SYS' 
    and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
    group by table_name;

因此,例如在此查询中,我想为每个将增加1的table_name元素添加一个序列,并且将在下一个分组时重置将增加一个BUT的column_name的每次迭代的一个序列。

伪代码

<table_description>
  <table_sequence>1</table_sequence>
  <table_name>xyz</table_name>
  <table_columns>
    <column_sequence>1</column_sequence>
    <column_name>Column One</column_name>
    <column_sequence>2</column_sequence>
    <column_name>Column two</column_name>
  </table_columns>
<table_description>
  <table_sequence>2</table_sequence>
  <table_name>abs</table_name>
  <table_columns>
    <column_sequence>1</column_sequence>
    <column_name>Column One</column_name>
    <column_sequence>2</column_sequence>
    <column_name>Column two</column_name>
  </table_columns>
<table_description>

1 个答案:

答案 0 :(得分:1)

您可以将from all_tab_columns更改为通过dense_rank()生成序列号的内联视图:

from (
  select atc.*,
    dense_rank() over (order by table_name) as table_sequence,
    dense_rank() over (partition by table_name order by column_name) as column_sequence
  from all_tab_columns atc
  where owner='SYS' 
  and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
)

然后您可以在XML中使用这些生成的列:

select XMLROOT ( xmlagg(
                   xmlelement(
                     "table_description", 
                      xmlelement(
                        "table_name",
                        table_name
                      ),
                      xmlelement(
                        "table_sequence",
                        table_sequence
                      ),
                      xmlelement(
                        "table_columns",
                        xmlagg(
                          xmlforest(
                          column_name as "column_name",
                          column_sequence as "column_sequence"
                          )
                        )
                      )
                  )
            ), VERSION '1.0', STANDALONE YES) 
from (
  select atc.*,
    dense_rank() over (order by table_name) as table_sequence,
    dense_rank() over (partition by table_name order by column_name) as column_sequence
  from all_tab_columns atc
  where owner='SYS' 
  and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
)
where owner='SYS' 
and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
group by table_name, table_sequence;

得到:

<?xml version="1.0" standalone="yes"?>
<table_description>
  <table_name>ALL_APPLY_ENQUEUE</table_name>
  <table_sequence>1</table_sequence>
  <table_columns>
    <column_name>DESTINATION_QUEUE_NAME</column_name>
    <column_sequence>1</column_sequence>
    <column_name>RULE_OWNER</column_name>
    <column_sequence>3</column_sequence>
    <column_name>RULE_NAME</column_name>
    <column_sequence>2</column_sequence>
  </table_columns>
</table_description>
<table_description>
  <table_name>ALL_APPLY_EXECUTE</table_name>
  <table_sequence>2</table_sequence>
  <table_columns>
    <column_name>EXECUTE_EVENT</column_name>
    <column_sequence>1</column_sequence>
    <column_name>RULE_OWNER</column_name>
    <column_sequence>3</column_sequence>
    <column_name>RULE_NAME</column_name>
    <column_sequence>2</column_sequence>
  </table_columns>
</table_description>
<table_description>
  <table_name>ALL_APPLY_KEY_COLUMNS</table_name>
  <table_sequence>3</table_sequence>
  <table_columns>
    <column_name>APPLY_DATABASE_LINK</column_name>
    <column_sequence>1</column_sequence>
    <column_name>OBJECT_OWNER</column_name>
    <column_sequence>4</column_sequence>
    <column_name>OBJECT_NAME</column_name>
    <column_sequence>3</column_sequence>
    <column_name>COLUMN_NAME</column_name>
    <column_sequence>2</column_sequence>
  </table_columns>
</table_description>

您生成的XML仍然不正确,因为每列与其序列号之间没有链接。也许你想要更像的东西:

select XMLROOT ( xmlagg(
                   xmlelement(
                     "table_description", 
                      xmlelement(
                        "table_name",
                        table_name
                      ),
                      xmlelement(
                        "table_sequence",
                        table_sequence
                      ),
                      xmlelement(
                        "table_columns",
                        xmlagg(
                          xmlelement(
                            "column_description", 
                            xmlforest(
                              column_name as "column_name",
                              column_sequence as "column_sequence"
                            )
                          )
                        )
                      )
                  )
            ), VERSION '1.0', STANDALONE YES) 
from (
  select atc.*,
    dense_rank() over (order by table_name) as table_sequence,
    dense_rank() over (partition by table_name order by column_name) as column_sequence
  from all_tab_columns atc
  where owner='SYS' 
  and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
)
where owner='SYS' 
and table_name in ('ALL_APPLY_ENQUEUE','ALL_APPLY_EXECUTE','ALL_APPLY_KEY_COLUMNS') 
group by table_name, table_sequence;

得到:

<?xml version="1.0" standalone="yes"?>
<table_description>
  <table_name>ALL_APPLY_ENQUEUE</table_name>
  <table_sequence>1</table_sequence>
  <table_columns>
    <column_description>
      <column_name>DESTINATION_QUEUE_NAME</column_name>
      <column_sequence>1</column_sequence>
    </column_description>
    <column_description>
      <column_name>RULE_OWNER</column_name>
      <column_sequence>3</column_sequence>
    </column_description>
    <column_description>
      <column_name>RULE_NAME</column_name>
      <column_sequence>2</column_sequence>
    </column_description>
  </table_columns>
</table_description>
<table_description>
  <table_name>ALL_APPLY_EXECUTE</table_name>
  <table_sequence>2</table_sequence>
  <table_columns>
    <column_description>
      <column_name>EXECUTE_EVENT</column_name>
      <column_sequence>1</column_sequence>
    </column_description>
    <column_description>
      <column_name>RULE_OWNER</column_name>
      <column_sequence>3</column_sequence>
    </column_description>
    <column_description>
      <column_name>RULE_NAME</column_name>
      <column_sequence>2</column_sequence>
    </column_description>
  </table_columns>
</table_description>
<table_description>
  <table_name>ALL_APPLY_KEY_COLUMNS</table_name>
  <table_sequence>3</table_sequence>
  <table_columns>
    <column_description>
      <column_name>APPLY_DATABASE_LINK</column_name>
      <column_sequence>1</column_sequence>
    </column_description>
    <column_description>
      <column_name>OBJECT_OWNER</column_name>
      <column_sequence>4</column_sequence>
    </column_description>
    <column_description>
      <column_name>OBJECT_NAME</column_name>
      <column_sequence>3</column_sequence>
    </column_description>
    <column_description>
      <column_name>COLUMN_NAME</column_name>
      <column_sequence>2</column_sequence>
    </column_description>
  </table_columns>
</table_description>