2013-04-05 77 views
0

我试图与Sybase ASE 15.0.2以下,但发现很难打通:Sybase ASE的XMLTABLE - 模式不工作

的动机是提取的<表>标签的内容。有人可以帮助我吗?

参考 - 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 

回答

0

在我上面的问题,我试图避免循环,并尝试使用XMLTABLE(),因此它就像一个查询。但是,事实证明,对于像多个表和列xml这样的更复杂结构(在我的问题中,我提到了单表和多列xml的基本情况),xmltable()有点僵化。 所以,我要通过“xmlextract()+循环”的方式。 这里是多个表/多列的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 
0

做在1个查询而不WHILE或Coursor

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