简体   繁体   中英

How to pass a list of parameter to stored procedure and perform batch insert in SQL Server

I'm using Spring JDBCTemplate to connect to the SQL Server.

I have a list of Objects that needed to be inserted into a table of SQL Server.

What I did is the following:

public void batchInsert(final List<Bean> list) {

    final String sql = "insert into temp"
            + "(id, name, amount, location, time, price) "
            + " values (?, ?, ?, ?, ?, ?)";

    getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {

        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            Bean vo = list.get(i);
            ps.setString(1, vo.getId());
            ps.setString(2, vo.getName());
            ps.setDouble(3, vo.getAmount());
            ps.setString(4, vo.getLocation());
            ps.setString(5, vo.getTime());
            ps.setDouble(6, vo.getPrice());
        }

        @Override
        public int getBatchSize() {
            return list.size();
        }
    });
}

But now, I'd like to pass the parameter List<Bean> list to a stored procedure which handle the batch insert as high efficient as possible.

May I ask how to implement this?

First of all don't write query directly as it can be security breach to Your application. For bulk data storage the way normally get followed is XML Way. Try to implement it through XML.

You can use Table variable parameter for your stored procedure :

CREATE TYPE RecordList AS TABLE (Id Int, Name NVarChar(100), Amount int, location nvarchar(100), ...)

CREATE PROCEDURE test 
    @RecordList dbo.RecordList READONLY
AS Begin
    Insert Into temp (id, name, amount, location , ...)
    Select id, name, amount, location, ...)
    from @RecordList
End

I don't work with Spring JDBCTemplate but you can use following reference in order to use table variable parameter in C#:

How to pass table value parameters to stored procedure from .net code

C# and Table Value Parameters

如果不能使用表值参数,为什么不在存储过程中使用xml参数?

Pasre XML to dataset:

DECLARE @ParseXML xml

--SET @ParseXML  = ?        Your xml, don't use UTF-8
SET  @ParseXML = '
<row>
  <id>1</id>
  <name>Alex</name>
  <amount>3</amount>
  <location>GBR</location>
  <time>2014-02-27T08:25:19.113</time>
  <price>5.25</price>
</row>
<row>
  <id>2</id>
  <name>John</name>
  <amount>1</amount>
  <location>USA</location>
  <time>2014-02-27T08:25:19.113</time>
  <price>3.00</price>
</row>
<row>
  <id>3</id>
  <name>Sam</name>
  <amount>4</amount>
  <location>CAN</location>
  <time>2014-02-27T08:25:19.113</time>
  <price>7.55</price>
</row>
';

--INSERT INTO Temp
SELECT
    T.c.value('./id[1]','int') as id
    ,T.c.value('./name[1]','nvarchar(255)') as name
    ,T.c.value('./amount[1]','int') as amount
    ,T.c.value('./location[1]','nvarchar(255)') as location
    ,T.c.value('./time[1]','datetime') as [time]
    ,T.c.value('./price[1]','money') as [time]
FROM @ParseXML.nodes('//row') T(c);

XML Stored procedures are available since SQL 2005

basically, you declare an input parameter of xml type in your procedure declaration.

then, in your procedure, you could use different methods to parse xml. Maybe the easiest is to use the OPENXML method and sp_xml_preparedocument/sp_xml_removedocument

Suppose your xml variable is something along this:

<Order>
    <OrderID>12345</OrderID>
    <CustomerID>ABCD-1234</CustomerID>
    <OrderDate>20140101</OrderDate>
</Order>

Procedure should be something like :

CREATE PROCEDURE MyProc @xmlData xml
AS

EXEC sp_xml_preparedocument @i OUTPUT, @xmlData

select *
from
  openxml (@i, '/ROOT/Order', 1)
  with
  ( OrderID        int
  , CustomerID     nchar(5)
  , OrderDate      datetime)
  INTO MyOrders

EXEC sp_xml_removedocument @i

see: http://technet.microsoft.com/it-it/library/ms186918.aspx on how to use OPENXML

While a table-valued parameter or constructing XML is the modern approach, if that's not available to you or you don't want that overhead, you could simply concatenate the many INSERT statements and send them in as a single batch to SQL Server. If you need to do some processing as part of the insertion, you the batch could use a temporary table which would be accessible to a stored procedure called at the end of the batch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM