在SqlServer 2005中查询XML列中的不同数据

时间:2010-10-12 01:46:10

标签: sql-server

我有一些xml数据存储在sql server 2005的表中的XML列中。

Record1会有该列的数据如下所示:

<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany">
  <Things>
    <Thing>
        <Name>Monkey</Name>
    </Thing>
    <Thing>
        <Name>Lion</Name>
    </Thing>
    <Thing>
        <Name>Shoe</Name>
    </Thing>
  </Things>
</ArrayOfThings>

记录2可能包含该列的数据

<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany">
  <Things>
    <Thing>
        <Name>Monkey</Name>
    </Thing>
    <Thing>
        <Name>Elephant</Name>
    </Thing>
    <Thing>
        <Name>Hammer</Name>
    </Thing>
    <Thing>
        <Name>Bucket</Name>
    </Thing>
  </Things>
</ArrayOfThings>

任何人都可以帮助我解决从该表中选择不同内容的语法。

返回的结果如下所示: 猴 狮子 鞋 象 锤子 桶

显然这不是生产数据:)

设置脚本:

CREATE TABLE [SomeSchema].[MyTable](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ThingData] [xml] NULL,
 CONSTRAINT [PK_Party] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)
) ON [PRIMARY]
GO

INSERT INTO [SomeSchema].[MyTable]
           ([ThingData])
     VALUES
           ( 
'<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany">
  <Things>
    <Thing>
        <Name>Monkey</Name>
    </Thing>
    <Thing>
        <Name>Lion</Name>
    </Thing>
    <Thing>
        <Name>Shoe</Name>
    </Thing>
  </Things>
</ArrayOfThings>
')
GO

INSERT INTO [SomeSchema].[MyTable]
           ([ThingData])
     VALUES
           (
'<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany">
  <Things>
    <Thing>
        <Name>Monkey</Name>
    </Thing>
    <Thing>
        <Name>Elephant</Name>
    </Thing>
    <Thing>
        <Name>Hammer</Name>
    </Thing>
    <Thing>
        <Name>Bucket</Name>
    </Thing>
  </Things>
</ArrayOfThings>
')
GO

并且选择将违反表格中的列

3 个答案:

答案 0 :(得分:1)

您还可以轻松使用SQL Server 2005内置XQuery语言而不是笨重的OPENXML内容,并轻松实现相同的结果:

DECLARE @input XML 
SET @input = '<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany">
  <Things>
    <Thing>
        <Name>Monkey</Name>
    </Thing>
    <Thing>
        <Name>Elephant</Name>
    </Thing>
    <Thing>
        <Name>Hammer</Name>
    </Thing>
    <Thing>
        <Name>Bucket</Name>
    </Thing>
  </Things>
</ArrayOfThings>'

;WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/SomeCompany' AS ns)
SELECT
    DISTINCT Array.Things.value('(ns:Name)[1]', 'varchar(50)')
FROM
    @input.nodes('/ns:ArrayOfThings/ns:Things/ns:Thing') AS Array(Things)

你基本上创建了一个名为Array.Things的“伪表”,它为该指定类型的每个条目包含一个“行” - 这里给定的结构中有一个<Thing>

然后,您可以访问这些“行”并抓取单个元素,此处为<Name>值,您可以选择这些元素并使用它们。

答案 1 :(得分:1)

create table #t1(id int not null identity(1,1),ThingData xml)

insert #t1(ThingData) values ( '<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany"> <Things> <Thing> <Name>Monkey</Name> </Thing> <Thing> <Name>Lion</Name> </Thing> <Thing> <Name>Shoe</Name> </Thing> </Things></ArrayOfThings>')

insert #t1(ThingData) values ( '<ArrayOfThings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SomeCompany"> <Things> <Thing> <Name>Monkey</Name> </Thing> <Thing> <Name>Elephant</Name> </Thing> <Thing> <Name>Hammer</Name> </Thing> <Thing> <Name>Bucket</Name> </Thing> </Things></ArrayOfThings>')

;WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/SomeCompany' AS ns) select DISTINCT Array.Things.value('(ns:Name)[1]', 'varchar(50)') from #t1 cross apply #t1.[ThingData].nodes('/ns:ArrayOfThings/ns:Things/ns:Thing') as Array(Things)

答案 2 :(得分:0)

如果要使用

  

设置脚本:
  CREATE TABLE [SomeSchema]。[MyTable](....

来自问题,然后:

WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/SomeCompany' AS ns) 
select DISTINCT Array.Things.value('(ns:Name)[1]', 'varchar(50)') Name 
FROM    [SomeSchema].[MyTable] MT
CROSS APPLY 
MT.ThingData.nodes('/ns:ArrayOfThings/ns:Things/ns:Thing') 
AS Array(Things)