您的位置:首页 > 数据库

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

2008-12-20 13:56 573 查看
实现批量操作是常见的任务,比如批量删除一批数据,如果在应用程序端循环调用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 参考:/article/5386412.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐