OpenXML
I created procedure which make use of OpenXML function of the sql server which allow to insert multiple record in one time. OpenXML require xml string of record to insert data in the database.
I created procedure which make use of OpenXML function of the sql server which allow to insert multiple record in one time. OpenXML require xml string of record to insert data in the database.
ALTER PROCEDURE [dbo].[Ins_Employee]
( @XmlString text )
AS
BEGIN
SET NOCOUNT ON
BEGIN TRANSACTION
Begin Try
DECLARE @XMLDocPointer INT
EXEC sp_xml_preparedocument @XMLDocPointer OUTPUT, @XmlString
INSERT INTO Employee
(Name, Email, PhoneNo)
SELECT Name,Email,PhoneNo
FROM OPENXML(@XMLDocPointer,
'/ROOT/DATA'
,2)
WITH (Name VARCHAR(50),--
'@Name'
,
Email VARCHAR(50),--
'@Email'
,
PhoneNo VARCHAR(50) --
'@PhoneNo'
)
EXEC sp_xml_removedocument @XMLDocPointer
COMMIT TRANSACTION
Return 0;
End Try
Begin Catch
ROLLBACK TRANSACTION
End Catch
END
As you see in above procedure OpenXML make use of xmlDocument as input which is get created by system define procedure sp_xml_preparedocument which take xmlString as input and return XmlDocument.
Once OpenXML done task of insertion sp_xml_removedocument system proceudre is require to remove that element.
All record get inserted in once by the OpenXML function as I used transaction if the one record insertion fails all inserted record get rollback.
Following line of the code used to execute code i.e stored procedure
As you see in I am passing Element centric xml to the proceudre.
Exec Ins_Employee
'<root>
<data>
<name>pranay</name>
<email>pranayamr@gmail.com</email>
<phoneno>99007007</phoneno>
</data>
'
</root>
Note
If you are passing XML string as Attribute centric in it as in procedure than you need to define variable so the select statement in procedure will be
SELECT Name,Email,PhoneNo
FROM OPENXML(@XMLDocPointer,
'/ROOT/DATA'
,2)
WITH (Name VARCHAR(50)
'@Name'
,
Email VARCHAR(50)
'@Email'
,
PhoneNo VARCHAR(50)
'@PhoneNo'
)
Exec Ins_Employee
'<root>
<data email=
"pranayamr@gmail.com"
name=
"pranay"
phoneno=
"99007007"
>
</data></root>'
Now after done with the database , code part of the application is as below.
Uploaded Excel File which contains Employee data
Presentation layer
Following function in presentation layer read data from the excel file, which is uploaded on server.
private
void
ReadAndInsertExcelData()
{
int
i;
bool
blValid =
true
;
OleDbCommand ocmd;
OleDbDataAdapter oda;
DataTable dtDetails;
DataSet dsDetails;
OleDbConnection oconn =
new
OleDbConnection
(
@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source="
+
Server.MapPath(
"~/Upload/MonthlyActual.xls"
) + ";Extended
Properties=
'Excel 8.0;HDR=YES;IMEX=1'
");
try
{
ocmd =
new
OleDbCommand(
"select * from [Sheet1$]"
, oconn);
oda =
new
OleDbDataAdapter(ocmd);
dsDetails =
new
DataSet();
oda.Fill(dsDetails,
"DATA"
);
dtDetails = dsDetails.Tables[0];
dsDetails.DataSetName =
"ROOT"
;
i = 0;
DataRow[] drLst = dtDetails.Select("(Name
is
null
) or (Email
is
null
) or (PhoneNo
is
null
)");
if
(drLst.Count() > 0)
blValid =
false
;
if
(blValid)
{
XMLController xMLController =
new
XMLController();
xMLController.Ins(BaseLineType, dtDetails);
}
}
catch
{
lblMsg.Text = ex.Message;
lblMsg.ForeColor = System.Drawing.Color.Red;
}
finally
{
lblMsg.Text =
"Data Inserted Sucessfully"
;
oda =
null
;
dtDetails =
null
;
dsDetails =
null
;
}
}
Business Layer
Function below takes DataTable as input and generate XML string, As you see below I used StringWriter which use StringBuilder object, DataTable make use of StringWriter and write XML string in StringBuilder object.
public
int
Ins(DataTable pImportTable)
{
int
IsSuccess = -100;
try
{
StringBuilder sbXMLString =
new
StringBuilder();
System.IO.StringWriter sw =
new
System.IO.StringWriter
(sbXMLString);
pImportTable.WriteXml(sw);
DALXML dALManualCost =
new
DALXML();
dALManualCost.Ins(sbXMLString.ToString());
IsSuccess = dALManualCost.IsSuccess;
}
catch
{
throw
;
}
return
IsSuccess;
}
Note:Above method generate Element centric XML string.
Now if you want to write out the Attribute centric xml file you just need to replace the line of datatable.WriteXml with the below code for loop also you dont require to use the StringWriter object.
sbXMLString.Append(
"<root>"
);
for
(
int
i = 0; i < pImportTable.Rows.Count; i++)
{
sbXMLString.Append(
"<DATA "
);
sbXMLString.Append(
"Name='"
+
pImportTable.Rows[i][0].ToString().Trim() +
"' "
);
sbXMLString.Append(
"Email='"
+ pImportTable.Rows
[i][1].ToString().Trim() +
"' "
);
sbXMLString.Append(
"PhoneNo='"
+
pImportTable.Rows[i][2].ToString().Trim() +
"' "
);
sbXMLString.Append(
" />"
);
}
sbXMLString.Append(
"</root>"
);
DataLayer
Now this layer call the stored procedure which pass the xmlstring of employee to database. Return parameter will tell that its successfull insert or not.
public
void
Ins(
string
pXMLString)
{
try
{
Database db = CommonHelper.GetDataBaseInstance();
DbCommand cmdXML = db.GetStoredProcCommand
(SP_INSERT_STAGINGMANUALCOSTMONTHLY);
db.AddInParameter(cmdXML,
"XmlString"
, DbType.String,
pXMLString);
db.AddParameter(cmdXML,
"ret"
, DbType.Int32,
ParameterDirection.ReturnValue,
""
, DataRowVersion.Current,
IsSuccess);
db.ExecuteNonQuery(cmdXML);
IsSuccess = Convert.ToInt32(db.GetParameterValue(cmdXML,
"ret"
));
}
catch
{
IsSuccess = -100;
throw
;
}
}
Note : This is the one technique I found useful to enter bulk amount of data in database in one transaction. There are also other available which might be more efficient than this
No comments:
Post a Comment