Reputation: 29159
The following code will return select $f/field/text() from table1
declare @x xml = '<meta><field>Column1</field></meta>';
select @x.query('
for $f in /meta
return
"select $f/field/text() from table1"
')
I tried to change the return part to "select"+$f/field
or "select" $f/field
and these cannot be parsed.
Update:
The @x
will be generated from a table with for xml raw,elements
. The purpose to use xml/xquery is to avoid the boilerplate string concatenations. It seems XQuery cannot transform xml to text?
Updated question:
The following is the code I want to write.
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() ")" }
')
And the generated result should be,
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)
Upvotes: 1
Views: 876
Reputation: 138960
Use .value instead of .query to get a value from XML.
declare @x xml = '<meta><field>Column1</field></meta>';
select 'select '+quotename(@x.value('(/meta/field)[1]', 'sysname'))+' from table1'
Result:
select [Column1] from table1
Update:
Here is a way to build your query using the meta table directly.
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, '')
Result:
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)
Upvotes: 2
Reputation: 7566
The solution:
--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
Upvotes: 1