技术开发 频道

如何使用SQL Server 2000中的XML功能(下)

【IT168技术频道】
 通过OPENXML插入
    现在我们将用下面的XML示例从中插入一个定单和两个定单细节行:
<Customer CustomerID='ALFKI'> <Order OrderDate='1/1/1972' Freight='3'> <Detail ProductID='1' Price='4' Quantity='10' Discount='0'/> <Detail ProductID='2' Price='5' Quantity='2' Discount='0'/> </Order> </Customer>
       首先,将该XML传递给图 7所示的存储过程,并使用sp_xml_preparedocument系统存储过程准备之。然后启动一个事务来包装INSERT语句,以便插入一个定单及其子记录。这样便可以在部分事务失败时回滚事务。接下来,使用在Customer\Order节点开始的OPENXML打开XML文档。利用WITH子句,将XML文档返回到Order元素(Customer 元素)的父节点,然后查看Customer元素的CustomerID属性值,从而获得CustomerID。这是OPENXML函数的一个重要功能,因为它让用户使用受限的XPath表达式来遍历XML文档,从而获得属性和元素值。

图 7 插入父定单及其子定单
CREATE PROCEDURE prInsertOrderAndOrderDetailsFromXML @sXML NTEXT AS DECLARE @iDoc int, @OrderID int EXEC sp_xml_preparedocument @iDoc output, @sXML IF @@Error<>0 BEGIN RETURN END BEGIN TRANSACTION INSERT INTO Orders (CustomerID , OrderDate, Freight) SELECT CustomerID, CAST(OrderDate As datetime), CAST(Freight AS money) FROM OpenXML(@iDoc,'/Customer/Order', 1) WITH (CustomerID nchar(5) '../@CustomerID' , OrderDate varchar(10) '@OrderDate', Freight varchar(12) '@Freight') IF @@Error<>0 BEGIN EXEC sp_xml_removedocument @iDoc ROLLBACK TRANSACTION RETURN END SET @OrderID=SCOPE_IDENTITY() INSERT INTO [Order Details] (OrderID, ProductID, UnitPrice, Quantity, Discount) SELECT @OrderID, ProductID, ProductPrice, ProductQTY, Discount FROM OpenXML(@iDoc,'/Customer/Order/Detail') WITH (ProductID int '@ProductID', ProductPrice money '@Price', ProductQTY smallint '@Quantity', Discount real '@Discount') IF @@Error<>0 BEGIN EXEC sp_xml_removedocument @iDoc ROLLBACK TRANSACTION RETURN END EXEC sp_xml_removedocument @iDoc COMMIT TRANSACTION SELECT @OrderID GO

    插入Order后,我们获取由内置的SQL Server SCOPE_IDENTITY函数刚刚生成的OrderID值。然后我们使用另一个INSERT语句(使用OPENXML函数从XML数据中获取Order Details)继续插入Order Details行。只要不出现错误,定单及其子定单细节行就被插入到其各自的数据库表中。

    SCOPE_IDENTITY方法使用单个Order及其子定单。不过,以一个XML批插入多个Order及其子定单的情况比较复杂。问题就是在具有多个Order记录的情况下,仍要能够将适当的定单映射到其子定单。由于不知道要关联哪些行,因此必须添加一些代码来处理这一问题。可以在WITH子句中使用@mp:id/@mp:parentid元属性来提供一种获取父定单的新OrderID并将其映射到其子定单的OrderID字段的方法。
0
相关文章