xml实战:一 把表转化为XML

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

 

 

--创建测试数据库

 

CREATE DATABASE TK431Chapter8

GO

 

USE TK431Chapter8

GO

 

--创建schema

declare @schema XML

SELECT @schema = c FROM OPENROWSET (

BULK 'C:/logRecordSchema.xsd', SINGLE_BLOB) AS TEMP(c)

CREATE XML SCHEMA COLLECTION LogRecordSchema AS @schema

 

--创建表

CREATE TABLE UniversalLog

( ID INT IDENTITY(1,1) NOT NULL,

LogDateTime DATETIME NOT NULL CONSTRAINT [DF_UniversalLog_LogDateTime]

DEFAULT (GetDate()),

ApplicationName NVARCHAR(50) NOT NULL,

LogRecord XML(LogRecordSchema) NULL )

 

--插入数据

INSERT UniversalLog(ApplicationName, LogRecord)

VALUES ( 'HR',

'<logRecord machine="server1" timestamp="2000-01-14T12:13:14Z">

<error number="1001">

<message>The user does not have enough permissions to execute query</message>

<module>DataAccessLayer</module>

</error>

</logRecord>')

 

 

INSERT UniversalLog(ApplicationName, LogRecord)

VALUES ('CustomerService',

'<logRecord machine="server2" timestamp="2000-01-15T12:13:14Z">

<post eventType="logOut"/>

<information flag="custom">

<message>User must change password on next login</message>

</information>

</logRecord>')

 

INSERT UniversalLog(ApplicationName, LogRecord)

VALUES ('HoursReport',

'<logRecord machine="server2" timestamp="2000-01-11T12:13:14Z">

<information flag="failure">

<message>Hard Disk with ID #87230283 is not responding</message>

</information>

<error number="18763">

<message>Application can not start</message>

<module>AppLoader</module>

</error>

<post eventType="appStart"/>

</logRecord>')

 

SELECT * FROM UniversalLog

 

 

--查询

USE AdventureWorks

GO

 

--FOR XML RAW

--每个字段作为属性

SELECT Department.[DepartmentID]

,History.[EmployeeID] 

,History.[StartDate]

,Department.[Name]

,DATEDIFF(year, History.[StartDate], GetDate()) AS YearsToDate

FROM HumanResources.Department, HumanResources.EmployeeDepartmentHistory History

WHERE Department.DepartmentID = History.DepartmentID

AND History.EndDate IS NULL

ORDER BY Department.[DepartmentID], History.[StartDate]

FOR XML RAW('OldestEmployeeByDepartment')

 

--每个字段作为子元素

SELECT Department.[DepartmentID]

,History.[EmployeeID] 

,History.[StartDate]

,Department.[Name] AS DepartmentName

,DATEDIFF(year, History.[StartDate], GetDate()) AS YearsToDate

FROM HumanResources.Department, HumanResources.EmployeeDepartmentHistory History

WHERE Department.DepartmentID = History.DepartmentID

AND History.EndDate IS NULL

ORDER BY Department.[DepartmentID], History.[StartDate]

FOR XML RAW('OldestEmployeeByDepartment'), ELEMENTS

 

--FOR XML AUTO 模式(嵌套的XML格式)

SELECT Department.[DepartmentID]

,History.[EmployeeID] 

,History.[StartDate]

,Department.[Name] AS DepartmentName

,DATEDIFF(year, History.[StartDate], GetDate()) AS YearsToDate

FROM HumanResources.Department, HumanResources.EmployeeDepartmentHistory History

WHERE Department.DepartmentID = History.DepartmentID

AND History.EndDate IS NULL

ORDER BY Department.[DepartmentID], History.[StartDate] FOR XML AUTO

 

SELECT Department.[DepartmentID]

,History.[EmployeeID] 

,History.[StartDate]

,Department.[Name] AS DepartmentName

,DATEDIFF(year, History.[StartDate], GetDate()) AS YearsToDate

FROM HumanResources.Department, HumanResources.EmployeeDepartmentHistory History

WHERE Department.DepartmentID = History.DepartmentID

AND History.EndDate IS NULL

ORDER BY Department.[DepartmentID], History.[StartDate] FOR XML AUTO, ELEMENTS

 

 

 

把表转化为XML

 

 

--FOR XML PATH 以元素为中心

 

 

USE AdventureWorks

GO

 

SELECT History.[StartDate] '@StartDate'

,Department.[DepartmentID] 'Department/@id'

,Department.[Name] 'comment()'

,History.[EmployeeID] 'Department/Employee/@id'

,'Years in role:' 'Department/Employee/data()'

,DATEDIFF(year, History.[StartDate], GetDate()) 'Department/Employee/data()'

FROM HumanResources.Department, HumanResources.EmployeeDepartmentHistory History

WHERE Department.DepartmentID = History.DepartmentID

AND History.EndDate IS NULL

ORDER BY Department.[DepartmentID], History.[StartDate] FOR XML PATH ('ForEachRow')

 

 

--如果希望针对NULL 值生成元素,则可以指定带有XSINIL ELEMENTS 指令

SELECT EmployeeID "@EmpID",

       FirstName  "EmpName/First",

       MiddleName "EmpName/Middle",

       LastName   "EmpName/Last"

FROM   HumanResources.Employee E, Person.Contact C

WHERE  E.EmployeeID = C.ContactID

AND    E.EmployeeID=1

FOR XML PATH, ELEMENTS XSINIL

 

 

SELECT

       ProductModelID,

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH

go

 

SELECT ProductModelID,

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML RAW, ELEMENTS

 

-- 以上两种模式结果一样

 

--如果指定零长度字符串,则将不生成包装元素。

SELECT ProductModelID,

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH ('')

Go

 

--生成的XML 将包含指定的行元素名称

SELECT ProductModelID,

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH ('ProductModel')

Go

 

--在以下查询中,指定的ProductModelID 列名以@ 开头,且不包含斜杠标记(/)。因此,在生成的XML 中,将创建包含相应列值的<row> 元素的属性。

SELECT ProductModelID as "@id",

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH ('ProductModelData')

go

 

--指定root 选项来添加单个顶级元素

SELECT ProductModelID as "@id",

       Name

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH ('ProductModelData'), root ('Root')

go

 

SELECT ProductModelID as "@id",

       NAME AS "SomeChild/ModelName"

FROM Production.ProductModel

WHERE ProductModelID=122 or ProductModelID=119

FOR XML PATH ('ProductModelData'), root ('Root')

go

 

 

--Instructions 列是xml 类型,因此指定了xml 数据类型的query() 方法来检索该位置

SELECT ProductModelID as "@id",

       Name,

       Instructions.query('declare namespace MI="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";

                /MI:root/MI:Location

              ') as ManuInstr

FROM Production.ProductModel

WHERE ProductModelID=7

FOR XML PATH ('ProductModelData'), root ('Root')

go

 

 

 --使用WITH XMLNAMESPACES 绑定和在FOR XML 查询中使用前缀首先定义命名空间的前缀

 WITH XMLNAMESPACES (

   'uri1' as ns1, 

   'uri2' as ns2,

   'http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' as MI)

SELECT ProductModelID as "ns1:ProductModelID",

       Name           as "ns1:Name",

       Instructions.query('

                /MI:root/MI:Location

              ')

FROM Production.ProductModel

WHERE ProductModelID=7

FOR XML PATH ('ns2:ProductInfo'), root('ns1:root')

go

 

 

--使用PATH 模式生成值列表

 

SELECT ProductModelID     as "@ProductModelID",

       Name               as "@ProductModelName",

      (SELECT ProductID as "data()"

       FROM   Production.Product

       WHERE  Production.Product.ProductModelID =

              Production.ProductModel.ProductModelID

       FOR XML PATH ('')) as "@ProductIDs",

       (SELECT Name as "ProductName"

       FROM   Production.Product

       WHERE  Production.Product.ProductModelID =

              Production.ProductModel.ProductModelID

        FOR XML PATH ('')) as "ProductNames"

FROM   Production.ProductModel

WHERE  ProductModelID= 7 or ProductModelID=9

FOR XML PATH('ProductModelData')

 

--PATH 模式查询将构造带命名空间的XML

 

SELECT 'en'    as "English/@xml:lang",

       'food'  as "English",

       'ger'   as "German/@xml:lang",

       'Essen' as "German"

FOR XML PATH ('Translation')

go

 

-- 利用TYPE生产XML类型

DECLARE @myXML XML

SET @myXML = (SELECT 100 'col1',

200 'col2',

NULL 'col3',

400 'col4'

FOR XML RAW, ELEMENTS XSINIL, TYPE)

SELECT @myXML

 

--嵌套

SELECT Department.[DepartmentID],

Department.[Name],

(

SELECT EmployeeDepartmentHistory.[EmployeeID] 

,EmployeeDepartmentHistory.[StartDate]

,DATEDIFF(year, EmployeeDepartmentHistory.[StartDate], GetDate()) AS

YearsToDate

FROM HumanResources.EmployeeDepartmentHistory

WHERE Department.DepartmentID = EmployeeDepartmentHistory.DepartmentID

AND EmployeeDepartmentHistory.EndDate IS NULL

ORDER BY EmployeeDepartmentHistory.[StartDate]

FOR XML RAW('Employee'), TYPE

) AS Employees

FROM HumanResources.Department

ORDER BY Department.[DepartmentID]

FOR XML RAW('Department'), ELEMENTS, ROOT ('OldestEmployeeByDepartment')

 

 

 

 

--FOR XML EXPLICIT模式太复杂可以用FOR XML PATH代替

 

 

posted @ 2009-02-17 09:57  深潭  阅读(337)  评论(0编辑  收藏  举报