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代替
出处:http://www.cnblogs.com/dbasys/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。