OpenXML – all-in-one processing data

by ion.robu 23. October 2008 16:23

Introduction

The XML standard  is an intense used standard, because confers possibility to “carry” in a easy and fully understandable way information between different entities, belonging to different application on contained in same application. Capability of an XML “message” to be configurable and processed, due of its “architecture” recommends it as an ideal “transporter” to communicate with outside world, receiving and sending information. As the time passed, more and more technologies started to use XML standard, while the new ones (such as BizTalk) made from XML technology a “cornerstone”, relying their entire philosophy on XML.

 

XML in SQL Server usage

                Obviously, a very powerful technology, such SQL Server, which is one of the most used RDBMS in the world, could not avoid using the XML standard. Among XML standard utilization, we distinguish 3 of most important SQL mechanisms based on XML technology.

1.     Receive XML data

2.     Return XML data

3.     Storing XML data

Receive XML data

Through this mechanism, we can receive XML documents from another applications and use further within SQL statements in order to insert/update/delete/select data. This is a very useful feature in some cases, such as:

-       SQL statements (stored procedure, function) are called by applications which use XML as basic model of representing data (for example, BizTalk Server). In this case, is difficult to process the message before to send it to SQL statement in order to send just individual values, but is easier to send entire XML message to SQL statement and to process it there.

-       In case of a bulk insert/update/delete operations from applications which call SQL statements. In this case, is inappropriate to get component fields of every row to be inserted, and send them to SQL statement, because, for each row, we must open a connection to SQL Server, execute the statement with these fields as parameters, and close connection. For a bigger number of this kind of calls, it is obviously that performance of application and SQL server also will be affected. Instead, we can send entire batch as an XML document, and perform the insert/update/delete operations from within SQL statement (usually, a stored procedure). Of course, in case of multiple deleting operation, we can construct a document which contains only the elements constituting the primary key of table(s) from within rows will be deleted, and perform the deletion for that records.

Example

 

Let’s discuss on following scenario:

-       An ASP.NET application – Visual C# 2005, framework 2.0 – we will call it Company

-       In Company application, we will have a page, Customers.aspx, where, when we will press a button, we will receive a dataset with customers, from a data provider (imported from another database or file, received from a web service etc.). In our case, will be an XML file stored in application.

-       After we will receive the dataset with customers, we will insert in our database using openxml function.

To import the customers from file Customers.xml from directory solution to database, the steps are:

1.     On a new or existing database, run script CustomerTable.sql from SQlFiles folder, to add table TblCustomer

2.     On the same database run the script usp_InsertCustomers.sql from same folder, to add stored procedure usp_InsertCustomers

3.     Install application Companies on IIS server and open it with URL http://localhost/Companies.aspx

4.     Click on button ‘Import customers’. If the import goes correctly, will appear the message “Customers were inserted

5.     Check in table TblCustomer, to see the customers imported

What happened in the back? There are some operations which occurs when button ‘Import customers’ is pressed. The operations are:

1.     The content of the Customers.xml file is loaded in a DataSet object. When xml content is loaded, DataSet object identifies automatically the tables existing in xml structure, creates them, am populates them with data from xml. Normally, we should use a xml schema to check if xml content matches an expected structure and, thus, to avoid error. But, in this example, to simplify the model, we will consider a valid structure coming from xml file.

For this, we have the function

private DataSet LoadCustomersData()

{

DataSet dsCustomers = new DataSet("Customers");

dsCustomers.ReadXml(Server.MapPath("Customers.xml"));

return dsCustomers;

}

2.     The DataSet object is outputted to a string, which is passed to a DAL function, to be inserted in database

 

protected void ImportCustomers_Click(object sender, EventArgs e)

{

DataSet dsCustomers = LoadCustomersData();

StringWriter swCustomers = new StringWriter();

dsCustomers.WriteXml(swCustomers, XmlWriteMode.IgnoreSchema);

InsertCustomers(swCustomers.ToString());

}

private void InsertCustomers(string xmlCustomers)

{

lblResult.Text = CompaniesDAL.Customers.InsertCustomers(xmlCustomers);

      }

Of course, we can pass the xml file content to a DAL method directly, without using DataSet object. Here, we consider the possibility to receive this xml content to a various data sources, and in some cases, using a DataSet object may be useful, so, we used Dataset object.

3.     DAL method passes the xml string to a stored procedure, as a parameter, in order to be inserted in table TblCustomer.

public static string InsertCustomers(string xmlCustomers)

{

string strConnectionConfigurationManager.

ConnectionStrings["TestSQLXML"].

ToString();

SqlConnection sqlConnection = new SqlConnection(strConnection);

 

SqlCommand sqlCommand = new SqlCommand();

sqlCommand.Connection = sqlConnection;

sqlCommand.CommandText = "usp_InsertCustomers";

sqlCommand.CommandType = CommandType.StoredProcedure;

//pass xml string as parameter

SqlParameter sqlParam = new SqlParameter("@xmlCustomers", SqlDbType.VarChar, 8000);

sqlParam.Value = xmlCustomers;

sqlCommand.Parameters.Add(sqlParam);

 

try

{

sqlConnection.Open();

sqlCommand.ExecuteNonQuery();

}

catch (Exception ex)

{

return ex.Message;

}

finally {

if(sqlConnection.State == ConnectionState.Open)

sqlConnection.Close();

}

return "Customers were inserted";

}

 

4.     Inserting the xml in table TblCustomers using procedure usp_InsertCustomers. Let’s take a closer look to this procedure

 

create procedure [dbo].[usp_InsertCustomers]

@xmlCustomers varchar(8000)

as

begin

declare @i int

exec sp_xml_preparedocument @i output, @xmlCustomers

insert into dbo.TblCustomer

select * from

openxml(@i, '/Customers/Customer', 2)

with

(

CustomerType int,

CustomerFirstName varchar(50),

CustomerLastName varchar(50),

CustomerBirthDate datetime

)

exec sp_xml_removedocument @i

end

                We can observe how the procedure makes the job:

-       It receives the xml content as a string (@xmlCustomers varchar(8000))

-       Uses the procedure sp_xml_preparedocument to create an internal representation of xml document based on string received. The procedure returns a handle, stored in variable @i, to identity the document in next operations

-       Next, is performed a SELECT operation over xml document

o     openxml procedure get the parameters:

§  @i – specifies which document must be processed, since @i handles the xml document associated with it by the procedure sp_xml_preparedocument called earlier

§  it is specified the level from where the selection must be done ('/Customers/Customer')

§  last parameter Indicates the mapping that should be used between the XML data and the relational rowset, and how the spill-over column should be filled. Possible values are:

·         0 Defaults to attribute-centric mapping.

·         1 Use the attribute-centric mapping. Can be combined with XML_ELEMENTS; in which case, attribute-centric mapping is applied first, and then element-centric mapping is applied for all columns not yet dealt with.

·         2 Use the element-centric mapping. Can be combined with XML_ATTRIBUTES; in which case, attribute-centric mapping is applied first, and then element-centric mapping is applied for all columns not yet dealt with.

·         8 Can be combined (logical OR) with XML_ATTRIBUTES or XML_ELEMENTS.
In context of retrieval, this flag indicates that the consumed data should not be copied to the overflow property @mp:xmltext.

In our example, this parameter will take value 2, because our xml document is element-centric.

o    with clause specifies the structure of dataset that will be filled by select operation. Thus, we define columns that come from xml document:

§  CustomerType int

§  CustomerFirstName varchar(50)

§  CustomerLastName varchar(50)

§  CustomerBirthDate datetime

The columns must match with columns from TblCustomer, to be able to perform insert operation

-       Rows returned by select statement will be inserted in TblCustomer table.

insert into dbo.TblCustomer

select * from openxml...

-       After insert, we must release resources involved in these operations

exec sp_xml_removedocument @ifree memory occupied by xml document, associated with @i handle

Using this mechanism, we performed a SQL operation over multiple records. In this way, we reduce the number of operations of opening/closing SQL connections, increasing the performance. More than that, passing the XML document on the SQL server and processing there gives us the possibility to put all processing in one place, making developer’s life easier.

               

OpenXML.rar (31.76 kb)

Tags:

Comments

Comments are closed

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentComments

Comment RSS

Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar