博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用WSS的Lists.UpdateListItems()方法之被截断的CAML
阅读量:7204 次
发布时间:2019-06-29

本文共 4489 字,大约阅读时间需要 14 分钟。

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

   顺便再给出调用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,如需转载请自行联系原作者

你可能感兴趣的文章
Hyper-V损坏数据恢复报告
查看>>
《从零开始学Swift》学习笔记(Day 16)——字典集合
查看>>
[转]配置nginx+apache 其中动态由apache处理,静态由nginx处理
查看>>
在Word中如何实现"后退"?
查看>>
简明 Vim 练级攻略 | 酷壳 - CoolShell.cn
查看>>
养成逻辑的习惯
查看>>
jQuery attributes(上)
查看>>
ISO8583报文协议(转)
查看>>
Android文本框实现搜索和清空效果
查看>>
Logic-算法-XX部队XX侦察队员
查看>>
海量数据(数据量比较大时)的处理分析
查看>>
printf 规定数据输出方式
查看>>
Facebook Graph API(2)--读取数据之picture
查看>>
使用分析服务多维模式建立简单的分析模型
查看>>
Oracle Real Application Testing diagram
查看>>
IoC容器Autofac(2) - 一个简单示例(附demo源码)
查看>>
桥接模式 - 设计模式学习
查看>>
Google Maps Android API v2 (2)- 地图对象
查看>>
MySQL 5.5 手册下载
查看>>
hdu 1300(dp)
查看>>