SQL 2005 xml 處理的一些sample

 

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
t.c.query('text()') AS [Name]
FROM
@doc.nodes('people/person') AS t(c);

 

 

 

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>'
 
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'

 
/*

     ID Name  phone address
     1 benny  19313 ''
     2 skype  138 park
*/

 

SELECT

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

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

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

 

--其實XML相對路徑的問題,請確認是Namespace不確定還是XML節點路徑都不確定(如果是這樣,那麼設計的XML穩定性有待增強)。

--下面的Demo,是在解析多個Namespace的XML節點,但是路徑至少可以確定的:

 

     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節點下的SessionID和OrderNumber

     --;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')

 

 

--雖然XML的Namespace不確定,但是,我們可以確定XML的路徑,這樣子避免解析到其他節點的數據。

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

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

 

發佈了110 篇原創文章 · 獲贊 5 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章