将XML与Transact-SQL一起使用

时间:2014-06-18 18:01:59

标签: tsql xml-parsing sql-server-2008-r2

我在SQL Server 2008 R2中工作。我有大约20个数据库都具有相同的结构。我不完全确定我的代码出错了。如果有人可以指出我的错误或指出我对这个问题的一些资源,那将不胜感激。

我正在运行的代码是:

create table #temp 
([Client] varchar(100), [Language_Code] char(100))

exec sp_msforeachdb '
if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name =  ''LicenceInfoes'')
begin
DECLARE @MyXML XML
Declare @lang_code char(100)

set @lang_code = ''(SELECT a.b.value''(''Laguages[1]'',''char(100)'')'' FROM @MyXML.nodes(''Licence'') a(b))''
insert into #temp select ''?'', @lang_code  
end
'

select * from #temp

drop table #temp

最终结果是这个错误:

  

Msg 102,Level 15,State 1,Line 7
  ' Laguages [1]'。

附近的语法不正确

所需的输出将是一个包含2列的表格,如下所示:

<DB_Name> <Language_Codes>
  Name1      en-GB, en-US 

原始查询在单独执行时工作正常,并为我提供了我正在寻找的数据,但我想立即对所有数据库运行它以节省一些时间并允许自动化过程

DECLARE @MyXML XML

SET @MyXML = (select LicenceData from LicenceInfoes where Id='1001')

SELECT 
    a.b.value('Laguages[1]', 'char(100)') AS Language_Codes 
FROM 
    @MyXML.nodes('Licence') a(b)

以及存储在其中一个DB中的样本XML

<Licence xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Clients />
  <LastUpdated>2014-06-03T15:59:46.9831585Z</LastUpdated>
  <CustomerId>9999999</CustomerId>
  <CustomerName>xxxxx</CustomerName>
  <ContactEmail>someone@somewhere.com</ContactEmail>
  <Type>Commercial</Type>
  <Languages>
    <Language>en-GB</Language>
    <Language>en-US</Language>
  </Languages>
  <DefaultLanguagePack>en-GB</DefaultLanguagePack>

感谢您的任何帮助。

修改

在尝试了一些事情之后,我找到了错误所在的位置。

错误在@MyXML变量中:

SET @MyXML = ''(select LicenceData from t.LicenceInfoes)''

将t.LicenceInfoes更改为?.. LicenceInfoes修复了我遇到的问题。

4 个答案:

答案 0 :(得分:1)

这有帮助吗?

DECLARE @Tbl TABLE (ID INT NOT NULL, XmlContent XML)

INSERT INTO @tbl VALUES(1, '<Licence xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Clients />
  <LastUpdated>2014-06-03T15:59:46.9831585Z</LastUpdated>
  <CustomerId>9999999</CustomerId>
  <CustomerName>xxxxx</CustomerName>
  <ContactEmail>someone@somewhere.com</ContactEmail>
  <Type>Commercial</Type>
  <Languages>
    <Language>en-GB</Language>
    <Language>en-US</Language>
  </Languages>
  <DefaultLanguagePack>en-GB</DefaultLanguagePack></Licence>')

SELECT
    ID,
    XT.XC.value('(.)[1]', 'varchar(50)')
FROM 
    @Tbl
CROSS APPLY
    XmlContent.nodes('/Licence/Languages/Language') AS XT(XC)

这会产生一个输出:

ID  (No column name)
1   en-GB
1   en-US

答案 1 :(得分:0)

我认为这可能有所帮助。

exec sp_msforeachdb '
if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name =  ''LicenceInfoes'')
begin
DECLARE @MyXML XML
Declare @lang_code char(100)
SET @MyXML = (select LicenceData from t.LicenceInfoes)
set @lang_code = (SELECT a.b.value(''Laguages[1]'',''char(100)'') FROM @MyXML.nodes(''Licence'') a(b))
insert into #temp select ''?'', @lang_code  
end'

我不理解if ''?'' like ''%''的含义,但现在,查询在语法上是正确的。

答案 2 :(得分:0)

我认为您的错误是由于第7行的Laguages[1]拼写错误造成的。将其更改为Languages[1],它应该会生成正确的输出。

答案 3 :(得分:0)

尝试了一些选项后,我最终得到了以下错误:

Msg 208, Level 16, State 1, Line 7
Invalid object name 'LicenceInfoes'.

我意识到我在设置@MyXML变量的代码部分犯了一个错误。

它是:

SET @MyXML = (select LicenceData from LicenceInfoes)

在表名修改之前添加“?..”。

SET @MyXML = (select LicenceData from ?..LicenceInfoes)

由于marc_s,我最终更新了我的代码。现在它看起来像这样:

create table Tbl (Client varchar(max), Language_Code varchar(max))
exec sp_msforeachdb '
    if ''?'' like ''%'' and exists(select * from ?.sys.tables t where t.name =  ''LicenceInfoes'')

begin
SET QUOTED_IDENTIFIER ON

INSERT INTO Tbl

SELECT
    ''?'', 
    a.b.value(''(.)[1]'',''varchar(100)'') AS Language_Codes 
FROM ?..LicenceInfoes 
cross apply LicenceData.nodes(''/Licence/Laguages/Language'') a(b)
end'

select * from Tbl

drop table Tbl

这与他的例子中的marc_s完全相同,这就是我想要的。

感谢大家的回复和帮助!