• SQLServer2005中利用xml类型实现批量操作的存储过程[原]


    实现批量操作是常见的任务,比如批量删除一批数据,如果在应用程序端循环调用DAL.Entity.Delete则效率非常低,因为数据库往返次数取决与数据量大小。而编写一个存储过程效率更高。

    做这个批量操作的存储过程使用什么作为参数是一个问题。如果使用VARCHAR(MAX),内容是,例如要删除记录的id并以逗号隔开,例如“1,2,3,4,…..”,这样的话就会存在最大长度受限制的问题。

    这儿介绍一种使用XML的VARBINARY类型作为参数的高效方法。

    首先是xml的格式:



    <
    Employees>
     <Employee EmployeeID="1" EmployeeName="Bush" EmployeeAddress="WashtonD.C." />
     <Employee EmployeeID="2" EmployeeName="Jamson" EmployeeAddress="Russia" />
     <Employee EmployeeID="3" EmployeeName="Brown" EmployeeAddress="London" />
    </Employees>

    把这个XML转换为Binary类型:

    using System.IO;
    using System.Xml;
     
    private byte[] GetEmployeesListXmlStream(IList EmployeesList)
    {
       byte[] result = null;
     
       using (MemoryStream stream = new MemoryStream())
       {
             XmlWriterSettings settings = new XmlWriterSettings();
     
             settings.Indent = true;
             settings.OmitXmlDeclaration = true;
             settings.IndentChars = "\t";
             XmlWriter writer = XmlWriter.Create(stream, settings);
     
             writer.WriteStartDocument();
             writer.WriteStartElement("Employees");
     
             foreach (Employee var in EmployeesList)
             {
                 writer.WriteStartElement("Employee");
                 writer.WriteAttributeString("EmployeeID", var.EmployeeID.ToString());
                 writer.WriteAttributeString("EmployeeName", var.EmployeeName);
                 writer.WriteAttributeString("EmployeeAddress", var.EmployeeAddress);
                 writer.WriteEndElement();
             }
     
             writer.WriteEndElement();
             writer.WriteEndDocument();
     
             writer.Flush();
             writer.Close();
             result = stream.ToArray();
       }
       
       return result;
    }

    大家也知道,DataSet中的数据可以直接序列化成xml,通过dataSet.GetXml(),然后转化为binary即可。

    XML的VARBINARY类型作为参数,批量删除的存储过程

       1: CREATE PROCEDURE [dbo].[_Employee_BulkDelete]    
       2: (    
       3:     @EmployeeList VARBINARY(MAX)
       4: )    
       5: AS    
       6:  
       7:     --XML ----
       8:     DECLARE @EmployeeListXML XML;
       9:  
      10:     -- TABLE to store XML records ----
      11:     DECLARE @TempEmployees TABLE
      12:     (
      13:         EmployeeID BIGINT NULL,
      14:         EmployeeName NVARCHAR(512) NULL DEFAULT(''),
      15:         EmployeeAddress NVARCHAR(512) NULL DEFAULT('')
      16:     )
      17:  
      18:     -- Get XML from binary stream -----
      19:     SET @EmployeeListXML = CONVERT(XML, @EmployeeList);
      20:  
      21:     -- Fill to table-------
      22:     INSERT INTO @TempEmployees    
      23:     (    
      24:         EmployeeID,
      25:         EmployeeName,
      26:         EmployeeAddress
      27:     )    
      28:     SELECT    
      29:         nref.value('@id', 'BIGINT'),
      30:         nref.value('@name', 'NVARCHAR(512)'),
      31:         nref.value('@address', 'NVARCHAR(512)')
      32:     FROM     
      33:         @EmployeeListXML.nodes('/Employees/Employee') R(nref)
      34:  
      35:     --- Delete ----Maybe more complicated routine here !----------
      36:  
      37:     DELETE [dbo].[TempEmployees]
      38:     FROM [dbo].[TempEmployees] AS T1
      39:       INNER JOIN @TempEmployees AS T2    
      40:             ON    (T1.EmployeeID = T2.EmployeeID)    
      41:     WHERE (EmployeeSalary > 500000)

    最后,如果想进一步优化该存储过程的效率,可以优化索引,使用临时表等。


    ------- 批量插入可以用SqlBulkCopy 参考:http://www.cnblogs.com/xiaoweinet/archive/2010/03/02/1676478.html

  • 相关阅读:
    网页HTML到8.20前
    数据库SQLServer
    构建之法读后感
    VS2013 生成安装文件
    工大助手(自动化部署)
    工大助手(用户名、密码错误提示)
    工大助手(验证码错误提示)
    工大助手(加权成绩计算)
    Wireshark插件编写
    微软认知服务——人脸识别
  • 原文地址:https://www.cnblogs.com/Mainz/p/1358898.html
Copyright © 2020-2023  润新知