SQL FOR XML 子句详解

数据库操作中,有时需要将查询结果以XML格式返回。传统的方法是使用存储过程,通过游标逐条处理记录,然后拼接字符串来生成XML。但这种方法效率低下,且代码复杂。幸运的是,SQL提供了一种更简洁高效的方法:FOR XML子句。本文将详细介绍如何使用FOR XML子句的RAW模式来生成XML数据。

要理解本文内容,需要具备基本的SQLJOIN知识。

使用代码

本文将使用以下数据库结构。可以复制粘贴以下代码来创建数据库,或者创建自己的数据库并调整查询。

CREATE DATABASE FOR_XML_TUTORIAL; USE [FOR_XML_TUTORIAL]; CREATE TABLE [CUSTOMER] ( CUSTOMER_ID INT PRIMARY KEY NOT NULL, FIRST_NAME VARCHAR(25) NOT NULL, LAST_NAME VARCHAR(25) NOT NULL, POSTAL_CODE VARCHAR(2) NOT NULL ); CREATE TABLE [ORDER] ( ORDER_ID INT PRIMARY KEY NOT NULL, CUSTOMER_ID INT NOT NULL REFERENCES CUSTOMER(CUSTOMER_ID), TOTAL_ITEMS INT NOT NULL, TOTAL_AMOUNT NUMERIC(18, 2) NOT NULL ); INSERT INTO CUSTOMER VALUES (1, 'John', 'Michaels', 'TX'); INSERT INTO CUSTOMER VALUES (2, 'Shawn', 'Cena', 'MA'); INSERT INTO CUSTOMER VALUES (3, 'Dwayne', 'Austin', 'TX'); INSERT INTO CUSTOMER VALUES (4, 'Steve', 'Johnson', 'FL'); INSERT INTO [ORDER] VALUES (1, 1, 5, 32.50); INSERT INTO [ORDER] VALUES (2, 1, 2, 21.36); INSERT INTO [ORDER] VALUES (3, 2, 7, 59.00); INSERT INTO [ORDER] VALUES (4, 3, 2, 18.24); INSERT INTO [ORDER] VALUES (5, 4, 3, 30.00); INSERT INTO [ORDER] VALUES (6, 4, 6, 66.00);

FOR XML模式

使用FOR XML子句时,必须指定一个模式,以返回相应的XML数据。以下是可用模式的列表:

  • RAW
  • AUTO
  • EXPLICIT
  • PATH

RAW模式

将使用以下查询来返回客户信息和订单信息。

SELECT C.FIRST_NAME, C.LAST_NAME, C.POSTAL_CODE, O.ORDER_ID, O.TOTAL_ITEMS, O.TOTAL_AMOUNT FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID

要返回RAW模式的XML数据,只需在上述查询中添加FOR XML RAW。

SELECT C.FIRST_NAME, C.LAST_NAME, C.POSTAL_CODE, O.ORDER_ID, O.TOTAL_ITEMS, O.TOTAL_AMOUNT FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW

上述查询返回的XML数据如下:

可以看到,查询返回的每条记录都被转换为一个名为"row"的XML元素,列名转换为属性名,属性值设置为查询返回的值。

要更改元素名称,可以在RAW关键字后添加所需的元素名称:

SELECT C.FIRST_NAME, C.LAST_NAME, C.POSTAL_CODE, O.ORDER_ID, O.TOTAL_ITEMS, O.TOTAL_AMOUNT FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW('Customer')

上述查询返回的XML数据中,每个元素的名称从"row"更改为"Customer"。

要更改属性名称,只需为列提供别名:

SELECT C.FIRST_NAME AS 'FirstName', C.LAST_NAME AS 'LastName', C.POSTAL_CODE AS 'PostalCode', O.ORDER_ID AS 'OrderId', O.TOTAL_ITEMS AS 'Items', O.TOTAL_AMOUNT AS 'Amount' FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW('Customer')

上述查询返回的数据中,属性名称已更改为新的别名。

要将每个元素嵌套在一个根元素中,可以在查询中添加ROOT关键字:

SELECT C.FIRST_NAME AS 'FirstName', C.LAST_NAME AS 'LastName', C.POSTAL_CODE AS 'PostalCode', O.ORDER_ID AS 'OrderId', O.TOTAL_ITEMS AS 'Items', O.TOTAL_AMOUNT AS 'Amount' FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW('Customer'), ROOT

返回的数据现在被嵌套在一个名为"root"的父元素中。

要更改根元素的名称,可以在ROOT关键字后添加所需的名称:

SELECT C.FIRST_NAME AS 'FirstName', C.LAST_NAME AS 'LastName', C.POSTAL_CODE AS 'PostalCode', O.ORDER_ID AS 'OrderId', O.TOTAL_ITEMS AS 'Items', O.TOTAL_AMOUNT AS 'Amount' FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW('Customer'), ROOT('Customers')

上述查询返回的数据中,根元素的名称已更改为"Customers"。

到目前为止,执行的所有查询都返回了将每列转换为属性的XML数据格式。要更改此格式,并将每列映射到自己的元素,可以在查询中添加ELEMENTS关键字:

SELECT C.FIRST_NAME AS 'FirstName', C.LAST_NAME AS 'LastName', C.POSTAL_CODE AS 'PostalCode', O.ORDER_ID AS 'OrderId', O.TOTAL_ITEMS AS 'Items', O.TOTAL_AMOUNT AS 'Amount' FROM [CUSTOMER] C INNER JOIN [ORDER] O ON C.CUSTOMER_ID = O.CUSTOMER_ID FOR XML RAW('Customer'), ROOT('Customers'), ELEMENTS

现在,每条记录的属性被转换为一个元素,其名称设置为别名,值设置为查询返回的值。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485