0

我正在使用 Sybase ASE 15.0.2 尝试以下操作,但发现很难通过:

动机是提取 <tables> 标签的内容。有人可以帮我解决这个问题吗?

参考 - http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc30020.1502/html/xmlb/CFHIDCJC.htm

declare @purgeTableInfo varchar(16300)
select @purgeTableInfo = 
    '<purge>
        <start-time>00:00:000</start-time>
        <end-time>03:00:000</end-time>
        <tables>
            <table>
                <table_name>table1</table_name>
                <owner>dbo</owner>
                <columns>
                    <column>
                        <column_name>column1</column_name>
                        <column_value>121212xdfsdsdsdsd</column_value>
                        <column_condition>like</column_condition>
                    </column>
                    <column>
                        <column_name>column2</column_name>
                        <column_value>121212xdfsdsdsdsd</column_value>
                        <column_condition>like</column_condition>
                    </column>
                </columns>
            </table>
        </tables>
    </purge>'
        select * 
          from xmltable('/purge/tables/table/columns/column'
                    passing @purgeTableInfo
                    columns columnName varchar(255) path 'column_name',
                            tableName varchar(255) pattern '../../table_name') as purgeInputDetails
4

2 回答 2

0

在我上面的问题中,我试图避免循环并尝试使用 xmltable() 以便它就像一个查询。但是,事实证明,对于更复杂的结构,如多表和多列 xml,xmltable() 有点僵化(在我的问题中,我提到了单表和多列 xml 的基本情况)。所以,我将采用“xmlextract()+looping”的方式。这是多表/多列xml的解决方案:

declare @i int
declare @extractedTable varchar(50)
declare @j int
declare @extractedColumn varchar(50)
select @i = 1
select @extractedTable = ''

while (@extractedTable != null)
begin
    select @extractedTable=convert(varchar(50),xmlextract ('/purge/tables/table['+convert(varchar(5),@i)+']/table_name/text()', @purgeTableInfo))
    print "%1!", @extractedTable

    if(@extractedTable != null)
    begin
        select @j = 1
        select @extractedColumn = ''
        while (@extractedColumn != null)
        begin
            select @extractedColumn=convert(varchar(50),xmlextract ('/purge/tables/table['+convert(varchar(5),@i)+']/columns/column['+convert(varchar(5),@j)+']/column_name/text()', @purgeTableInfo))
            print "%1!", @extractedColumn
            if(@extractedColumn != null)
            begin
                insert into tabCols select @extractedTable as tableName, @extractedColumn as columnName
                select @j = @j+1
            end
        end
        select @i = @i+1
    end
end
commit
于 2013-04-09T14:46:33.837 回答
0

在没有 WHILE 或游标的情况下在 1 个查询中执行此操作

declare @XML text
select @XML = 
    '<purge>
        <start-time>00:00:000</start-time>
        <end-time>03:00:000</end-time>
        <tables>
            <table>
                <table_name>table1</table_name>
                <owner>dbo</owner>
                <columns>
                    <column>
                        <column_name>column1</column_name>
                        <column_value>121212xdfsdsdsdsd</column_value>
                        <column_condition>like</column_condition>
                    </column>
                    <column>
                        <column_name>column2</column_name>
                        <column_value>121212xdfsdsdsdsd</column_value>
                        <column_condition>like</column_condition>
                    </column>
                </columns>
            </table>
        </tables>
    </purge>'
    
select
  P.starttime
, P.endtime
, T.table_name
, T.owner
, C.column_name
, C.column_value
, C.column_condition
from
  --<purge>
  xmltable('/purge'
  passing @XML
  columns 
    ROW_NUM int for ordinality
  , starttime time path 'start-time'
  , endtime time path 'end-time'
  ) AS P
  --/purge/tables/table  
  LEFT JOIN xmltable('/tables/table'
  passing ISNULL(CAST(xmlextract('/purge['+convert(varchar(5), P.ROW_NUM)+']/tables', @XML) as VARCHAR(16000)), '<tables><table></table></tables>')
  columns
    ROW_NUM int for ordinality
  , table_name varchar(50) path 'table_name'
  , owner varchar(100) path 'owner'
  ) AS T ON 1 = 1
  --/purge/tables/table/columns/column 
  LEFT JOIN xmltable('/columns/column'
  passing ISNULL(CAST(xmlextract('/purge['+convert(varchar(5), P.ROW_NUM)+']/tables/table['+convert(varchar(5), T.ROW_NUM)+']/columns', @XML) as VARCHAR(16000)), '<columns><column></column></columns>')
  columns
    ROW_NUM int for ordinality
  , column_name varchar(50) path 'column_name'
  , column_value varchar(500) path 'column_value'
  , column_condition varchar(50) path 'column_condition'  
  ) AS C ON 1 = 1     
 

于 2017-08-18T13:54:41.527 回答