使用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,如需转载请自行联系原作者


相关文章
|
4月前
|
JSON Linux 网络安全
curl 使用及调用url时带有&符号被截断解决
curl 使用及调用url时带有&符号被截断解决
360 0
|
12月前
|
JavaScript
拼接中文参数时,报错is not defined
拼接中文参数时,报错is not defined
32 0
|
JSON PHP 数据格式
PHP中json传递请求字符串网址函数http_build_query()与parse_str(),将POST参数组转换拼接成GET请求链接
PHP中json传递请求字符串网址函数http_build_query()与parse_str(),将POST参数组转换拼接成GET请求链接
136 0
|
数据采集 Python
如何使用reduce(),filter()对数据进行求积,去除None,空字符串
如何使用reduce(),filter()对数据进行求积,去除None,空字符串
|
前端开发 PHP
TP5 使用strip_tags过滤html标签不起作用的解决方法
TP5 使用strip_tags过滤html标签不起作用的解决方法
283 0
|
JavaScript 前端开发 C#
Http请求,base64加号变空格
Http请求,base64加号变空格
748 0
.NET中将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),并使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
.NET中将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),并使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
343 0
input文件选择框文件过滤参数accept
input文件选择框文件过滤参数accept
111 0
【TP5】在视图给url追加俩个参数
【TP5】在视图给url追加俩个参数
106 0
【TP5】在视图给url追加俩个参数