使用WSS的Lists.UpdateListItems()方法之被截断的CAML

简介:

Microsoft的WSS(Windows Sharepoint Services)公开了很多用于访问和管理Sharepoint站点的方法,在调用这些方法时可以通过CAML(Collaborative Application Markup Language)进行一些操作。其中Lists.UpdateListItems()方法提供了用于向Sharepoint List增、删、改数据的方法,但是需要通过CAML语句告诉Sharepoint如何更新数据,有关如何使用CAML以及如何编写CAML进行List数据更新,读者可以参考微软的MSDN文档。

http://msdn.microsoft.com/zh-cn/library/websvclists.lists.updatelistitems.aspx

   顺便再给出调用Sharepoint站点的Web Service的地址:

http://Sitename/_vit_bin/lists.asmx?op=UpdateListItems

   在使用Lists.UpdateListItems方法时,所使用的用于更新数据的CAML类似于下面这样:

复制代码
< Batch  OnError ="Continue" >
    
< Method  ID ="1"  Cmd ="New" >
        
< Field  Name ="Title" > Hello < Field >
        
< Field  Name ="Document" > 5 </ Field >
   
</ Method >
   
< Method  ID ="2"  Cmd ="New" >
        
< Field  Name ="Title"   > World </ Field >
        
< Field  Name ="Document" > 5 </ Field >
   
</ Method >
</ Batch >
复制代码

   也就是说我们可以在同一段CAML中批量操作数据。不过最近在实际应用中遇到了一个问题,那就是当我要更新的记录太多,比如20000行,可能我需要写一段特别长的CAML,这个时候当我们在程序中调用Web Service时WSS会给出这样的错误。

Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries.

   就是说你所使用的CAML语句太长而被自动截断了。细心观察一下,发现被截断的CAML的前半部分已经成功执行到List中了,而后半部分没有被执行,看来我们需要自己动手来处理这个Bug了。最好的办法就是将过长的CAML分批进行处理,一部分一部分地执行。

复制代码
 1  ///   <summary>
 2           ///  Breaks a larg CAML query into smaller batches to avoid the error "Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries."
 3           ///   </summary>
 4           ///   <param name="listService"> The SharePoint list service to execute the CAML against. </param>
 5           ///   <param name="listName"> The name of the list to execute the CAML against. </param>
 6           ///   <param name="elementLargeBatch"> The CAML batch list of commands to be broken up. </param>
 7           ///   <param name="intBatchSize"> The size of batches to use.  If unsure use 300, it seems to work fairly well. </param>
 8           ///   <returns> Returns the status of each method block posted through the updates parameter and can 
 9           ///  be assigned to a System.Xml.XmlNode object. </returns>
10           public   static  XmlNode UpdateListItems(SqlClrSharePointSynchronizer.Lists.Lists listService,  string  listName, XmlElement elementLargeBatch,  int  intBatchSize)
11          {
12               //  calculate useful information
13               int  intMethodCount  =  elementLargeBatch.ChildNodes.Count;
14               int  intBatchCount  =  ( int )Math.Ceiling(( double )intMethodCount  /  ( double )intBatchSize);
15 
16               //  prepare xml documents for batches and results
17              XmlDocument xmlDocBatch  =   new  XmlDocument();
18              XmlDocument xmlDocResults  =   new  XmlDocument();
19              XmlElement elementResults  =  xmlDocResults.CreateElement( " Results " );
20 
21               try
22              {
23                   //  for each batch
24                   for  ( int  intCurrentBatch  =   0 ; intCurrentBatch  <  intBatchCount; intCurrentBatch ++ )
25                  {
26                       int  intMethodStart  =  intCurrentBatch  *  intBatchSize;
27                       int  intMethodEnd  =  Math.Min(intMethodStart  +  intBatchSize  -   1 , intMethodCount  -   1 );
28 
29                      XmlElement elementSmallBatch  =  CreateBatch(xmlDocBatch);
30 
31                       //  for each method in the batch
32                       for  ( int  intCurrentMethod  =  intMethodStart; intCurrentMethod  <=  intMethodEnd; intCurrentMethod ++ )
33                      {
34                          XmlElement element  =  (XmlElement)elementLargeBatch.ChildNodes[intCurrentMethod];
35                          elementSmallBatch.AppendChild(xmlDocBatch.ImportNode(element,  true ));
36                      }
37 
38                       //  execute the batch
39                      XmlNode nodeBatchResult  =  listService.UpdateListItems(listName, elementSmallBatch);
40 
41                       //  add the results of the batch into the results xml document
42                       foreach  (XmlElement elementResult  in  nodeBatchResult.ChildNodes)
43                      {
44                          elementResults.AppendChild(xmlDocResults.ImportNode(elementResult,  true ));
45                      }
46 
47                       //  clean up
48                      xmlDocBatch.RemoveAll();
49                  }
50              }
51               catch  (SoapException ex)
52              {
53                   if  (ex.Detail  ==   null )
54                  {
55                       throw ;
56                  }
57 
58                   // copy the exception detail into the Message so it will be available to SQL.
59                   throw   new  SoapException(ex.Detail.InnerText, ex.Code, ex.Actor, ex.Detail, ex);
60              }
61 
62               return  (XmlNode)elementResults;
63          }
64 
65  ///   <summary>
66           ///  Create the batch element. e.g. &lt;Batch OnError="Continue"&gt;&lt;/Batch&gt;
67           ///   </summary>
68           ///   <param name="xmlDoc"> The object of XmlDocument. </param>
69           ///   <returns> Return the Batch element. </returns>
70           private   static  XmlElement CreateBatch(XmlDocument xmlDoc) 
71          {
72              XmlElement elementBatch  =  xmlDoc.CreateElement( " Batch " );
73              elementBatch.SetAttribute( " OnError " " Continue " );
74               return  elementBatch;
75          }
复制代码

   我在使用的过程中发现超过600行的数据更新就会出现CAML被截断的情况,所以我干脆将intBatchSize设置为300,超过300行的CAML将会被分批执行。在Web Service中使用CAML经常会遇到这样或那样的问题,查询用的CAML问题更多,不过Microsoft在SP对象中对CAML的支持还是不错的,毕竟是经过封装的,使用起来要顺手许多。



本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2009/03/20/1417792.html,如需转载请自行联系原作者


相关文章
|
存储 弹性计算 运维
阿里云服务器ECS经济型e实例详细介绍_性能测试和租用价格
阿里云服务器ECS经济型e实例详细介绍_性能测试和租用价格,阿里云服务器ECS推出经济型e系列,经济型e实例是阿里云面向个人开发者、学生、小微企业,在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器,CPU采用Intel Xeon Platinum架构处理器,支持1:1、1:2、1:4多种处理器内存配比,e系列性价比优选
|
数据采集 运维 监控
|
人工智能 安全 前端开发
Copilot插件:开启AI编程新篇章
Copilot插件:开启AI编程新篇章
707 0
|
安全 NoSQL 关系型数据库
使用cnpm搭建企业内部私有NPM仓库
cnpm是企业内部搭建npm镜像和私有npm仓库的开源方案。它同时解决了现有npm架构的一些问题。
1138 0
使用cnpm搭建企业内部私有NPM仓库
|
8月前
|
机器学习/深度学习 人工智能 数据处理
OpenBioMed:开源生物医学AI革命!20+工具链破解药物研发「死亡谷」
OpenBioMed 是清华大学智能产业研究院(AIR)和水木分子共同推出的开源平台,专注于 AI 驱动的生物医学研究,提供多模态数据处理、丰富的预训练模型和多样化的计算工具,助力药物研发、精准医疗和多模态理解。
381 1
OpenBioMed:开源生物医学AI革命!20+工具链破解药物研发「死亡谷」
|
11月前
|
机器学习/深度学习 人工智能 编解码
MV-Adapter:上交大、北航和 VAST 等联合开源多视图一致图像生成模型,将预训练的文生图扩散模型转为多视图生成器
MV-Adapter是由北京航空航天大学、VAST和上海交通大学联合开发的多视图一致图像生成模型。该模型能够将预训练的文本到图像扩散模型转化为多视图图像生成器,支持生成高分辨率的多视角图像。
751 18
MV-Adapter:上交大、北航和 VAST 等联合开源多视图一致图像生成模型,将预训练的文生图扩散模型转为多视图生成器
|
11月前
|
人工智能 机器人 芯片
《C++与类脑芯片:开启人工智能硬件新征程》
在人工智能快速发展的背景下,类脑芯片作为模仿人类大脑神经元结构的新型硬件,以其低功耗和高并行处理能力崭露头角。C++凭借其高效执行、强大内存管理和丰富的库支持,在类脑芯片的应用开发中展现出独特优势。二者结合不仅在智能感知、数据处理和机器人控制等领域带来突破,还为未来创新应用如智能诊断、个性化教育等开辟了广阔前景。尽管面临编程复杂性和生态不完善等挑战,但通过学术界、产业界和开源社区的合作,C++与类脑芯片有望推动人工智能迈向新高度。
306 12
|
前端开发 JavaScript 关系型数据库
基于 Vue2.0 + Nest.js 全栈开发的后台应用
Vue2 Admin 是一个基于 Vue2 和 Ant Design Pro 开发的前端项目,配合 Nest.js 构建的后端,提供了一个完整的全栈后台应用解决方案。该项目支持动态国际化、用户权限管理、操作日志记录等功能,适合全栈开发者学习参考。线上预览地址:https://vue2.baiwumm.com/,用户名:Admin,密码:abc123456。
211 0
基于 Vue2.0 + Nest.js 全栈开发的后台应用
|
机器学习/深度学习 人工智能 安全
GPT-4硬核揭秘:能力,操纵性,局限性,聊天GPT Plus等
OpenAI创建了 GPT-4,这是 OpenAI 扩大深度学习努力的最新里程碑...
722 0
|
存储 SQL Oracle
【历史最全】oracle 获取相应时间 (本周、上周、本月、上月、最近7、30、90天)
在我们使用Oracle数据库的时候,经常会遇到获取相应时间的需求,更甚者,有些涉及写存储过程的兄弟们更是频繁使用到。为了使用起来更加便利,特别留存此记录,便于之后查看。以下SQL均可执行,因为访问的是dual表,所以不需要创建表就能完成调试。
2075 0