我有一个XML,我在SQL中处理它以将数据传递到SQL Server表。
XML如下所示
<SearchProgramsResponse xmlns="http://api.abc.com/2011-03-01/">
<page>1</page>
<items>50</items>
<total>3129</total>
<programItems>
<programItem id="7779">
<name>Coolblue NL</name>
<adrank>5.4</adrank>
<categories>
<category id="34">Shopping & Mail Order Shops</category>
<category id="43">Other</category>
</programItem>
</programItems>
</SearchProgramsResponse>
现在我使用以下查询来获得结果
;with xmlnamespaces(default 'http://api.abc.com/2011-03-01/')
select
t1.c.value('@id', 'int') as id,
t1.c.value('(name/text())[1]', 'nvarchar(200)') as name,
t1.c.value('(adrank/text())[1]', 'decimal(29,2)') as adrank
from
@xmldata.nodes('SearchProgramsResponse/programItems/programItem') as t1(c)
但这里的xmlnamespaces default
值是硬编码的。我怎样才能使它成为传递的变量。
我尝试过动态SQL但收到错误 这是我正在尝试的
DECLARE @xmldata XML
SET @xmldata = N'<SearchProgramsResponse xmlns="http://api.abc.com/2011-03-01/">
<page>1</page>
<items>50</items>
<total>3129</total>
<programItems>
<programItem id="7779">
<name>Coolblue NL</name>
<adrank>5.4</adrank>
<categories>
<category id="34">Shopping & Mail Order Shops</category>
<category id="43">Other</category>
</programItem>
</programItems>
</SearchProgramsResponse>';
DECLARE @d NVARCHAR(200)='http://api.abc.com/2011-03-01/'
DECLARE @ns NVARCHAR(max);
SET @ns = '
;with xmlnamespaces(default ' + @d +' )
select
t1.c.value(''@id'', ''int'') as id,
t1.c.value(''(name/text())[1]'', ''nvarchar(200)'') as name,
t1.c.value(''(adrank/text())[1]'', ''decimal(29,2)'') as adrank
from @xmldata.nodes(''SearchProgramsResponse/programItems/programItem'') as t1(c)';
exec sp_executesql @ns;
现在抛出错误
必须声明标量变量&#34; @ xmldata&#34;
因为它是变量而我正在执行动态SQL。
但如果我尝试更换它
SET @ns = REPLACE(@ns, '@xmldata', @xmldata);
EXEC sp_executesql @ns;
这将再次抛出错误,因为可以用整个XML替换表。
如果没有动态SQL,还有其他方法可以实现吗?
如果不能,我怎样才能获得动态SQL的结果?
由于
答案 0 :(得分:2)
如果查询中不需要命名空间,则可以使用通配符作为命名空间,并避免动态查询。
select
t1.c.value('@id', 'int') as id,
t1.c.value('(*:name/text())[1]', 'nvarchar(200)') as name,
t1.c.value('(*:adrank/text())[1]', 'decimal(29,2)') as adrank
from
@xmldata.nodes('*:SearchProgramsResponse/*:programItems/*:programItem') as t1(c);
答案 1 :(得分:1)
您需要将附加参数传递给sp_executesql
,该参数指定本地参数名称和该参数的值:
.....
.....
exec sp_executesql @ns, N'@xmldata XML', @xmldata=@xmldata;
<强> Sqlfiddle Demo
强>
答案 2 :(得分:0)
试试这个..
declare @t nvarchar (max)
set @t='DECLARE @xmldata XML '+'
SET @xmldata = ''<SearchProgramsResponse xmlns="http://api.abc.com/2011-03-01/">
<page>1</page>
<items>50</items>
<total>3129</total>
<programItems>
<programItem id="7779">
<name>Coolblue NL</name>
<adrank>5.4</adrank>
<categories>
<category id="34">Shopping & Mail Order Shops</category>
<category id="43">Other</category>
</categories>
</programItem>
</programItems>
</SearchProgramsResponse>'''
--
DECLARE @d NVARCHAR(200)='http://api.abc.com/2011-03-01/'
DECLARE @ns NVARCHAR(max);
DECLARE @ns2 NVARCHAR(max);
SET @ns = '
;with xmlnamespaces(default ''' + @d +''')
select
t1.c.value(''(@id)'', ''int'') as id,
t1.c.value(''(name/text())[1]'', ''nvarchar(200)'') as name,
t1.c.value(''(adrank/text())[1]'', ''decimal(29,2)'') as adrank
from @xmldata.nodes(''//SearchProgramsResponse/programItems/programItem'') as t1(c)
';
set @ns2=@t+@ns
print @ns2
exec(@ns2)