SQL2005 Tips XML 处理例子(1)

USE Test

--Create 2 tables as an example

CREATE TABLE ExampleTable

(

[ID] int PRIMARY KEY

,[Name] nvarchar(256)

)

CREATE TABLE ExampleTable2

(

[ID] int PRIMARY KEY

,[Name] nvarchar(256)

)

----way1

SELECT

*

FROM

sys.objects [table]

WHERE

[Name] LIKE 'ExampleTable%'

FOR XML AUTO, ROOT('tables')

 

--way2

SELECT[name] AS [@name], object_id AS [@object_id],

* FROM sys.objects

WHERE [Name] LIKE 'ExampleTable%'

FOR XML PATH('table'), ROOT('tables')

 

--SELECT * FROM sys.objects WHERE [Name] LIKE 'ExampleTable%'

 

--Way3

-------------------------------------

--Nested Results using FOR XML PATH--

-------------------------------------

-------------------------------------

--Nested Results using FOR XML PATH--

-------------------------------------

 

SELECT

t.[name] AS [@name]

,t.object_id AS [@object_id]

,t.[create_date] AS [date/@cdate]

,t.[modify_date] AS [date/mdate]

,CAST('<mydata>some random xml</mydata>' AS xml) [*]

,(

     SELECT

     c.[name] AS [@name]

     ,c.[column_id] AS [@column_id]

     ,c.[is_nullable] AS [@allows_nulls]

     ,ty.[name] AS [@datatype]

     FROM sys.columns c

     INNER JOIN sys.types ty ON c.[user_type_id] = ty.[user_type_id]

     WHERE   t.[object_id] = c.[object_id]

     FOR XML PATH('columns'), TYPE

)

FROM sys.objects t

WHERE [Name] LIKE 'ExampleTable%'

FOR XML PATH('table'), ROOT('tables')

 

 

SELECT  cdate, * FROM syscolumns WHERE id=1077578877

SELECT * FROM sysobjects WHERE id=1077578877

SELECT * FROM sys.objects WHERE object_id=1077578877

 

 

--------------------

--Set Xml Variable--

--------------------

/*

In 2000, it wasn't possible to set any variable to the result of a query

*/

DECLARE @xml xml

SELECT @xml =

(

SELECT TOP 3

[Name]

FROM sys.objects

FOR XML AUTO

)

SELECT @xml

 

 

 

/*

The query method allows reformatting of a document into other formats

It could be considered a little like XSLT

*/

DECLARE @doc xml

SET @doc =

'<people>

<person>Martin</person>

<person>Simon</person>

<person>Mark</person>

</people>'

SELECT @doc.query('

for $p in /people/person/text()

return

<root>

     <name>

     {$p}

     </name>

</root>

') AS queryresults

 

 

/*

The value method allows a single value to be extracted from an xml document

*/

DECLARE @doc xml, @count int,@name1 nvarchar(20)

DECLARE @maxName AS nvarchar(20)

 

SET @doc =

     '<people>

          <person>Martin</person>

          <person>Simon</person>

          <person>Mark</person>

     </people>'

SELECT @count = @doc.value('count(/people/person)', 'int')

SELECT @name1 = @doc.value('(/people/person/text())[2]','nvarchar(20)')

 

SELECT @count AS [count]

SELECT @name1 AS Name1

 

 

----------------------

--Using sql:variable--

----------------------

/*

It is not possible to construct a custom xquery string

However, it is possible to pass in a sql variables as parameters

to the XQuery statement.

NOTE: SQL must be sure that a single value will be returned,

hence the final [1], even though the statement

/people/person[sql:variable("@pos")]/text()

would only ever return 1 value

*/

DECLARE @doc xml, @pos int

SET @doc =

'<people>

<person>Martin</person>

<person>Simon</person>

<person>Mark</person>

</people>'

SELECT @pos = 2

SELECT @doc.value('(/people/person[sql:variable("@pos")]/text())[1]', 'nvarchar(256)')AS SecondName

SELECT @doc.value('(//people/person/text())[2]','nvarchar(20)')

 

 

/*

.nodes can be used to shred xml into a table

In 2000 we had to use OPENXML

*/

 

DECLARE @doc xml

SET @doc =

'<people>

<person>Martin</person>

<person>Simon</person>

<person>Mark</person>

</people>'

SELECT

PeopleTable.PersonColumn.query('text()') AS [Name]

FROM

@doc.nodes('people/person') AS PeopleTable(PersonColumn);

 

 

 

DECLARE @doc xml

SET @doc =

'<people>

     <person id=''1''>

          <name>benny</name>

          <name>aa</name>

          <phone>49313</phone>

          <address/>

     </person>

     <person id=''2''>

          <name>skype</name>

          <phone>138</phone>

          <address>park</address>

     </person>

</people>'

/*

     ID Name  phone address

     1 benny  19313 ''

     2 skype  138 park

*/

 

SELECT

     T.c.value('@id','char(1)') AS Id

     ,T.c.value('name[2]','nvarchar(20)')

     ,T.c.value('phone[1]','nvarchar(10)')

FROM @doc.nodes('/people/person') T(c)

WHERE T.c.value('@id','int') = 1

AND T.c.value('phone[1]','nvarchar(10)')='49313'

 

 

SELECT

PeopleTable.PersonColumn.query('/name/text()') AS [Name]

FROM @doc.nodes('/people/person') AS PeopleTable(PersonColumn)

WHERE PeopleTable.PersonColumn.value('@id','int') = 1

 

--use sql variables

DECLARE @doc xml

SET @doc =

'<people>

<person>Martin</person>

<person id=''1''>Simon</person>

<person>Mark</person>

</people>'

SELECT @doc.value()

 

 

--其实XML相对路径的问题,请确认是Namespace不确定还是XML节点路径都不确定(如果是这样,那么设计的XML稳定性有待增强)

--下面的Demo,是在解析多个NamespaceXML节点,但是路径至少可以确定的:

 

     DECLARE @XML xml

     SET @XML=N'

     <Publish xmlns="http://soa.newegg.com/SOA/USA/InfrastructureService/V10/PubSubService">

           <UserData xmlns="">

                 <SessionID>0xABde12345</SessionID>

                   <OrderNumber>1000</OrderNumber>

             <Node>

                   <SessionID>0xABde12345</SessionID>

                   <OrderNumber>102365</OrderNumber>

             </Node>

           </UserData>

     </Publish>'

 

     --这个是相对路径的解析方式,这种解析方式很容易出现解析到的数据不是我们想要的,比如,我们先想要的Node节点下的SessionIDOrderNumber

     --;WITH XMLNAMESPACES (DEFAULT 'http://soa.newegg.com/SOA/USA/InfrastructureService/V10/PubSubService')

     SELECT @XML.value('(//SessionID/text())[1]','CHAR(15)')

                 ,@XML.value('(//OrderNumber/text())[1]','int')

 

 

--虽然XMLNamespace不确定,但是,我们可以确定XML的路径,这样子避免解析到其他节点的数据。

SELECT @XML.value('(/*:Publish/*:UserData/*:Node/*:SessionID/text())[1]','CHAR(15)')

          ,@XML.value('(/*:Publish/*:UserData/*:Node/*:OrderNumber/text())[1]','int')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值