Sunday, November 2, 2008

Batch update list items using CAML

Scenario:
You want to batch update small amount of items in a list ( usually less then 100 in one time items ) 

Solution:
You can use CAML query to make the BULK update. Performace will degrade as the number of items to be updated increases. This example updates 100 items each time.

Code:

StringBuilder methodBuilder = new StringBuilder();
string batch = string.Empty;
DateTime currentDate = DateTime.Now;
string formattedDate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(currentDate);

string batchFormat = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<ows:Batch OnError=\"Return\">{0}</ows:Batch>";

string methodFormat = "<Method ID=\"{0}\">" +
"<SetList>{1}</SetList>" +
"<SetVar Name=\"Cmd\">Save</SetVar>" +
"<SetVar Name=\"ID\">{2}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Status\">{3}</SetVar>" +
"<SetVar Name=\"urn:schemas-microsoft-com:office:office#Status_x0020_Date\">{4}</SetVar>" +
"</Method>";

using (SPSite site = new SPSite("http://localhost"))
{
using (SPWeb web = site.OpenWeb())
{

// Get the list containing the items to update.
SPList list = web.Lists["Shared Documents"];
string listGuid = list.ID.ToString();

// Query to get the unprocessed items.
SPQuery query = new SPQuery();
query.Query = "<Where><Neq><FieldRef Name='Status'/>
<Value Type='Choice'>Open</Value></Neq></Where>";
query.ViewAttributes = "Scope='Recursive'";
query.RowLimit = 100;

SPListItemCollection unprocessedItems = list.GetItems(query);

do
{
SPListItemCollection unprocessedItems = list.GetItems(query);

//Process all the returned items in this page
// Build the CAML update commands.
for (int i = 0; i < unprocessedItems.Count; i++)
{
int itemID = unprocessedItems[i].ID;
methodBuilder.AppendFormat(methodFormat, itemID, listGuid, itemID, "In-Progess", formattedDate);
}

// Put the pieces together.
batch = string.Format(batchFormat, methodBuilder.ToString());

// Process the batch of commands.
string batchReturn = web.ProcessBatchData(batch);

query.ListItemCollectionPosition = unprocessedItems.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);
}
}
}
Article:http://msdn.microsoft.com/en-us/library/cc404818.aspx

1 comments:

Andreas Grabner January 26, 2009 at 4:00 PM  

Thanks for that sample.
I did some in-depth performance analysis of single-vs-batch updates in SharePoint
Check out my findings at dynaTrace Blog