65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 XML 保存主/从式表单

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (8投票s)

2004年4月15日

2分钟阅读

viewsIcon

71558

downloadIcon

1444

本文档展示了如何使用 XML 保存主/从式表单。

引言

数据库应用程序中最常见的表单类型之一是“主/从式”表单。保存这种表单的一种方法是循环遍历“从”部分,并将值插入到表中。更好的方法是将所有值一次性发送到 SQL Server,然后将它们全部插入到表中。我的代码正是这样做的。

使用代码

作为一个例子,我使用了两个表 PurchasePurchaseDetails;这两个表的模式如下

CREATE TABLE Purchase (
    InvoiceID numeric(18, 0) NOT NULL IDENTITY (1, 1),
    InvoiceDate datetime NOT NULL,
    SupplierName varchar(50) NULL
)
GO 
CREATE TABLE PurchaseDetails (
    InvoiceID int NOT NULL ,
    [Description] varchar (75) NOT NULL ,
    Quantity int NOT NULL ,
    Rate numeric(18, 2) NOT NULL , 
    Amount numeric(18, 2) NOT NULL
)

接下来是存储过程。存储过程必须接受 XML 字符串,该字符串可以是任何字符串数据类型。存储过程中需要遵循以下步骤

  1. 将值插入到主表中,在本例中为 Purchase
  2. 执行 sp_xml_preparedocument 以创建传递的 XML 的 XML 文档。
  3. 使用 OPENXML,将值插入到从表中,在本例中为 PurchaseDetails
  4. 最后但并非最不重要的一点,使用 sp_xml_removedocument 清理 XML 文档。

所有函数在 MSDN 中都有很好的文档记录,因此我将不再在此处解释它们。存储过程中的代码如下

CREATE PROC InsertPurchaseOrder (@InvoiceDate DATETIME, 
          @SupplierName VARCHAR(50), @PurchaseDetails NTEXT)
AS
BEGIN
     DECLARE @InvoiceID INT
     DECLARE @idoc INT

    INSERT INTO Purchase( InvoiceDate, SupplierName)
     VALUES (@InvoiceDate, @SupplierName)

     SET @InvoiceID = @@IDENTITY

    -- Create an internal representation of the XML document.
    EXEC sp_xml_preparedocument @idoc OUTPUT, @PurchaseDetails
    -- Insert the values in the details table
    INSERT PurchaseDetails (InvoiceID, [Description], Quantity, Rate, Amount)
    SELECT @InvoiceID, [Description], Quantity, Rate, Amount
    FROM OPENXML (@idoc, '/PurchaseOrder/Details', 2)
    WITH PurchaseDetails
    -- Destory the internal representation of the XML document.
    EXEC sp_xml_removedocument @idoc
END

在表单中,我创建了一个 DataTable 来保存采购订单的详细信息。将此 DataTable 添加到 DataSet 并将其转换为 XML 格式。

 private void CreateDT () {
    // Name is important this will be used in the stored proc 
    dtProd = new DataTable("Details"); 

    // Create the table structure 
    dtProd.Columns.Add("Description", 
       Type.GetType("System.String")).DefaultValue = ""; 
    dtProd.Columns.Add("Quantity", 
       Type.GetType("System.Int32")).DefaultValue = 0; 
    dtProd.Columns.Add("Rate", 
       Type.GetType("System.Decimal")).DefaultValue = 0.0; 
    dtProd.Columns.Add("Amount", Type.GetType("System.Decimal"), 
                                  "Rate * Quantity").ReadOnly = true;
}

private void btnSave_Click(object sender, System.EventArgs e) {
.
.
    ds.Tables.Add(dtProd); 
    DetailsXML = ds.GetXml();
.
.
}

需要记住的要点

  1. 运行包含在本文档中的 SQL 脚本。
  2. DataTable 的列名应与数据库中的列名相同。
  3. DataSet 名称和 DataTable 名称必须与存储过程中使用的名称匹配。

附加信息

我使用了 Microsoft 的数据访问应用程序块来执行存储过程。您可以在 此处 找到代码和文档。

© . All rights reserved.