Solved

Bulk Inserts with Stored Procedures

Posted on 2010-09-15
4
640 Views
Last Modified: 2012-05-10
Hello

I want a .net App to send data in bulk to a stored procedure, which will then use this data to delete all data in an existing table and perform a bulk insert.

Question: What type of variable do I use in my stored procedure?  Examples of code in .net that call a stored procedure with a 'bulk input' type of parameter? Example of a stored procedur that gets a 'bulk input' type of parameter and performs a bulk input

thanks
0
Comment
Question by:adimit
  • 3
4 Comments
 
LVL 5

Accepted Solution

by:
Vipul Patel earned 500 total points
ID: 33685176
I would prefer to use XML data type for bulk operations.
Please refer below example;

.NET code:


        public void BulkOperation()
        {
            string cns = @"Data Source=VIPSLAPTOP\SQLEXPRESS;Initial Catalog=ExpertsExchange;Integrated Security=SSPI;";
            string records = "<Operations>" +
                                    "<Delete>" +
                                        "<Row>" +
                                            "<ID>1</ID>" +
                                        "</Row>" +
                                        "<Row>" +
                                            "<ID>2</ID>" +
                                        "</Row>" +
                                    "</Delete>" +
                                    "<Insert>" +
                                        "<Row>" +
                                            "<ID>5</ID>" +
                                            "<Data>Five</Data>" +
                                        "</Row>" +
                                        "<Row>" +
                                            "<ID>6</ID>" +
                                            "<Data>Six</Data>" +
                                        "</Row>" +
                                    "</Insert>" +
                                    "<Update>" +
                                        "<Row>" +
                                            "<ID>3</ID>" +
                                            "<Data>vrluckyin</Data>" +
                                        "</Row>" +
                                    "</Update>" +
                                "</Operations>";
            SqlConnection cn = new SqlConnection(cns);
            cn.Open();
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = cn;
            cmd.CommandText = "BulkOperations";
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            SqlParameter parameter = new SqlParameter("@Records", System.Data.SqlDbType.Xml);
            parameter.Value = records;
            cmd.Parameters.Add(parameter);
            cmd.ExecuteNonQuery();
            cn.Close();
        }

NOTE: You can also use LINQ, EntityFramework, MDAC for data access code.
Stored Procedure:

/*
DECLARE @Records XML
SET @Records =
'
	<Operations>
		<Delete>
			<Row>
				<ID>1</ID>
			</Row>
			<Row>
				<ID>2</ID>
			</Row>
		</Delete>
		<Insert>
			<Row>
				<ID>5</ID>
				<Data>Five</Data>
			</Row>
			<Row>
				<ID>6</ID>
				<Data>Six</Data>
			</Row>
		</Insert>
		<Update>
			<Row>
				<ID>3</ID>
				<Data>vrluckyin</Data>
			</Row>
		</Update>
	</Operations>
'
EXEC BulkOperations @Records
*/
ALTER PROCEDURE [dbo].[BulkOperations]
@Records XML
AS
BEGIN
	;WITH DeleteRecords AS
	(
		SELECT 
			col.value('ID[1]','INT') AS ID
		FROM  @Records.nodes('//Delete/Row') tbl(col)
	)
	DELETE FROM Q_26475408
	WHERE ID IN (SELECT ID FROM DeleteRecords)
	
	;WITH InsertRecords AS
	(
		SELECT 
			col.value('ID[1]','INT') AS ID
			,col.value('Data[1]','VARCHAR(50)') AS Data
		FROM  @Records.nodes('//Insert/Row') tbl(col)
	)
	INSERT INTO Q_26475408
	(
		ID
		,Data
	)
	SELECT ID,Data FROM InsertRecords
	
	;WITH UpdateRecords AS
	(
		SELECT 
				col.value('ID[1]','INT') AS ID
				,col.value('Data[1]','VARCHAR(50)') AS Data
		FROM  @Records.nodes('//Update/Row') tbl(col)
	)
	UPDATE a
	SET a.Data = b.Data
	FROM Q_26475408 a
	INNER JOIN UpdateRecords b ON a.ID = b.ID 
	 
END

Open in new window

0
 
LVL 5

Assisted Solution

by:Vipul Patel
Vipul Patel earned 500 total points
ID: 33685199
Sorry ;) , I forgot to attach code for SQL table Q_26475408
CREATE TABLE [dbo].[Q_26475408](
	[ID] [int] NULL,
	[Data] [varchar](50) NULL
)

Open in new window

0
 

Author Comment

by:adimit
ID: 33695902
Every thing works fine within a stored procedure.

But I get an arithmentic overflow when inserting the following value into a datetime column.

<DTime>15/09/2000 10:00:00</DTime>

I get a similiar conversion error if I try the following:

<DTime>#15/09/2000 10:00:00#</DTime>

How do i store a date and time stamp.

see sample SP below:
ALTER PROCEDURE [dbo].[usp_InsertBatchLogFromPLC]
@Records XML
AS
BEGIN
      
      ;WITH InsertRecords AS
      (
            SELECT
                  col.value('UserName[1]','VARCHAR(50)') AS UserName
                  ,col.value('Phase[1]','VARCHAR(20)') AS Phase
                  ,col.value('DTime[1]','datetime') AS DTime
                  ,col.value('PT01A[1]','numeric(3,2)') AS PT01A
                  ,col.value('RTD01A[1]','numeric(3,2)') AS RTD01A
                  ,col.value('LOAD1[1]','numeric(3,2)') AS LOAD1
                  ,col.value('LOAD2[1]','numeric(3,2)') AS LOAD2
                  ,col.value('LOAD3[1]','numeric(3,2)') AS LOAD3
                  ,col.value('LOAD4[1]','numeric(3,2)') AS LOAD4
                  ,col.value('LOAD5[1]','numeric(3,2)') AS LOAD5
                  ,col.value('LOAD6[1]','numeric(3,2)') AS LOAD6
                  ,col.value('FoMin[1]','numeric(3,2)') AS FoMin
                  ,col.value('FoMax[1]','numeric(3,2)') AS FoMax
                  ,col.value('PhaseTime[1]','numeric(3,2)') AS PhaseTime
            FROM  @Records.nodes('//Logs/Row') tbl(col)
      )
      
      INSERT INTO Batch1Log
      (
            UserName,Phase,DTime,PT01A,RTD01A,LOAD1,LOAD2,LOAD3,LOAD4,LOAD5,LOAD6,
            FoMin,FoMax,PhaseTime
      )
      SELECT UserName,Phase,DTime,PT01A,RTD01A,LOAD1,LOAD2,LOAD3,LOAD4,LOAD5,LOAD6,
            FoMin,FoMax,PhaseTime FROM InsertRecords
      
END

GO

DECLARE @Records1 XML
SET @Records1 =
'
      <Operations>
            <Logs>
            <Row>
                        <UserName>Ant</UserName>
                        <Phase>PURGE</Phase>
                        <DTime>15/09/2000 10:00:00</DTime>
                        <PT01A>11.23</PT01A>
                        <RTD01A>100.55</RTD01A>
                        <LOAD1>12.56</LOAD1>
                        <LOAD2>156.98</LOAD2>
                        <LOAD3>900.23</LOAD3>
                        <LOAD4>45.34</LOAD4>
                        <LOAD5>90.14</LOAD5>
                        <LOAD6>345.67</LOAD6>
                        <FoMin>90</FoMin>
                        <FoMax>54</FoMax>
                        <PhaseTime>1.8</PhaseTime>
            </Row>
            <Row>
                        <UserName>Ant</UserName>
                        <Phase>PURGE</Phase>
                        <DTime>#15/09/2000 10:01:00#</DTime>
                        <PT01A>11.23</PT01A>
                        <RTD01A>100.55</RTD01A>
                        <LOAD1>12.56</LOAD1>
                        <LOAD2>156.98</LOAD2>
                        <LOAD3>900.23</LOAD3>
                        <LOAD4>45.34</LOAD4>
                        <LOAD5>90.14</LOAD5>
                        <LOAD6>345.67</LOAD6>
                        <FoMin>90</FoMin>
                        <FoMax>54</FoMax>
                        <PhaseTime>2.8</PhaseTime>
            </Row>
      </Logs>
            
      </Operations>
'


EXEC usp_InsertBatchLogFromPLC @Records1
0
 
LVL 5

Assisted Solution

by:Vipul Patel
Vipul Patel earned 500 total points
ID: 33698564
The reason is that you are using DD/MM/YYYY date format.

NOTE: 103 indicates DD/MM/YYYY date format.

Your query should be look like;


 
;WITH InsertRecords AS
      (
            SELECT 
                  col.value('UserName[1]','VARCHAR(50)') AS UserName
                  ,col.value('Phase[1]','VARCHAR(20)') AS Phase
                  ,CONVERT(DATETIME,col.value('DTime[1]','VARCHAR(50)'),103) AS DTime
                  ,col.value('PT01A[1]','numeric(3,2)') AS PT01A
                  ,col.value('RTD01A[1]','numeric(3,2)') AS RTD01A
                  ,col.value('LOAD1[1]','numeric(3,2)') AS LOAD1
                  ,col.value('LOAD2[1]','numeric(3,2)') AS LOAD2
                  ,col.value('LOAD3[1]','numeric(3,2)') AS LOAD3
                  ,col.value('LOAD4[1]','numeric(3,2)') AS LOAD4
                  ,col.value('LOAD5[1]','numeric(3,2)') AS LOAD5
                  ,col.value('LOAD6[1]','numeric(3,2)') AS LOAD6
                  ,col.value('FoMin[1]','numeric(3,2)') AS FoMin
                  ,col.value('FoMax[1]','numeric(3,2)') AS FoMax
                  ,col.value('PhaseTime[1]','numeric(3,2)') AS PhaseTime
            FROM  @Records.nodes('//Logs/Row') tbl(col)
      )

Open in new window

0

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now