2012-03-11 64 views
1

下面的代码将返回select $f/field/text() from table1如何在SQL Server 2005/2008中使用XQuery将xml转换为非xml文本?

declare @x xml = '<meta><field>Column1</field></meta>'; 
select @x.query(' 
for $f in /meta 
return 
    "select $f/field/text() from table1" 
') 

我试图返回部分更改为"select"+$f/field"select" $f/field这些不能被解析。


更新:
@x将从表产生具有for xml raw,elements。使用xml/xquery的目的是为了避免样板字符串连接。看来XQuery不能将xml转换为文本?


更新问题:
以下是我想要写的代码。

declare @meta table (field sysname primary key, validate varchar(8000)); 
insert into @meta values ('Col1', '< 100'), ('Col2', '> Col1'); 

declare @x xml = (select * from @meta for xml path('meta')); 
select @x; 

-- The following code cannot be parsed. It will be nice to replace /meta/field/text() with shorter variable too 
select @x.query(' 
    "select 1" 
     {"," /meta/field/text() "= case when" /meta/field/text() /meta/validate/text() "then" /meta/field/text()} 
    "from table1" 
    "where 1=1 " 
     { "or (" /meta/field/text() /meta/validate/text() ")" } 
') 

和产生的结果应该是,

select 1 
    , Col1 = case when Col1 < 100 then Col1 end 
    , Col2 = case when Col2 > Col1 then Col2 end 
from table1 
where 1=1 
     or (Col1 < 100) 
     or (Col2 > Col1) 

回答

0

只需要在外部XML标记来包装的一切。

1

解决办法:

--drop table #tmp 
declare @x xml = '<meta><field>Column1</field> <field>Column2</field></meta>'; 
declare @field varchar(max) 
CREATE TABLE #tmp (field varchar(max)) 

set @field = (select cast(@x.query('for $f in /meta/field 
return concat("insert into #tmp(field) select ", $f, " from table1;") 
') as varchar(max))) 

EXEC (@field); 

select field from #tmp 

drop table #tmp 
+0

$ f将包围。 – ca9163d9 2012-03-11 11:32:21

2

使用.value而不是.query摆脱XML值。

declare @x xml = '<meta><field>Column1</field></meta>'; 

select 'select '+quotename(@x.value('(/meta/field)[1]', 'sysname'))+' from table1' 

结果:

select [Column1] from table1 

更新:

这里是直接使用元表来构建查询的方式。

select 'select '+ 
     stuff((select ', '+field+' = case when '+field+' '+validate+' then '+field+' end' 
       from @meta 
       for xml path(''), type).value('.', 'nvarchar(max)'), 1, 2, '')+ 
     ' from table1 where '+ 
     stuff((select ' or ('+field+' '+validate+')' 
       from @meta 
       for xml path(''), type).value('.', 'nvarchar(max)'), 1, 4, '') 

结果:

select Col1 = case when Col1 < 100 then Col1 end, 
     Col2 = case when Col2 > Col1 then Col2 end 
from table1 
where (Col1 < 100) or 
     (Col2 > Col1) 
+0

谢谢。 @x将从具有'for xml raw,elements'的表中生成。使用xml/xquery的目的是为了避免样板字符串连接。看来XQuery不能将xml转换为文本? – ca9163d9 2012-03-11 20:04:25

+0

@NickW - XQuery功能非常强大。如果你可以更多地更新你的问题,那么你可能会有一些想法对你有所帮助。从XML中获取一些文本通常没有问题,但是我不明白你阅读你的问题所带来的问题。 – 2012-03-11 21:11:06

+0

@NickW - 用你正在使用的表更新你的问题,一些示例数据和预期的输出,也许有一些限制,如“请不要游标或循环”:) – 2012-03-11 21:14:31