2

I am inserting multiple rows in a table with single insert query using the following format:

INSERT INTO $table (field1,field2) VALUES (value1,value2),(values3,values4); 

The number of rows varies. Is there a way to use Perl's prepare statement for this kind of queries ?

For example, if I am inserting only one row I can do like the below:

$query = "INSERT INTO $table (field1,field2) VALUES (?,?)";
$sth = $dbh->prepare($query);
$sth->execute('value1','value2');

However, I want to do something like the below:

$values = '(value1,value2),(values3,values4),(values5,values6)';
$query = "INSERT INTO $table (field1,field2) VALUES ?";
$sth = $dbh->prepare($query);
$sth->execute($values);

Is this possible? or any other ways to achieve this ?

Kamrul Khan
  • 3,260
  • 4
  • 32
  • 59

2 Answers2

2

You can build up a query that can do what you want. Assuming that your records are in an array like this.

my @records = ( ['value1', 'value2'], ...) ;

Then you can create a query dynamically and execute it.

my $values = join ", ", ("( ?, ? )") x @records;
my $query  = "INSERT INTO $table (field1,field2) VALUES $values";
my $sth    = $dbh->prepare($query);
$sth->execute(map { @$_ } @$records);

Also in your example you are using string interpolation on the table name. Be careful with that as it can lead to database injections.

Q the Platypus
  • 825
  • 1
  • 7
  • 13
0

Put each record in its own array, then make an array of those:

my @records = ( [ 'value1', 'value2' ], [ 'value3', 'value4' ], [ 'value5', 'value6' ] );

Then prepare your INSERT statement:

my $query = "INSERT INTO $table (field1,field2) VALUES (?,?)";
my $sth = $dbh->prepare($query);

Then loop over your records and execute your statement handle for each one:

foreach my $rec ( @records ) { 
    $sth->execute( @$rec );
}
friedo
  • 65,762
  • 16
  • 114
  • 184
  • Thanks for your answer, we insert around 20000 rows per load. We found its much faster if we insert them all within one single insert query. Will it be as fast this way ? – Kamrul Khan Aug 21 '15 at 05:13
  • 3
    If you want it to be fast, skip Perl and use `LOAD DATA INFILE`. – friedo Aug 21 '15 at 05:14
  • 3
    A lot of that slowness could be caused by DBI committing each insertion individually. Try turning AutoCommit off before starting your loop. – Dave Cross Aug 21 '15 at 09:33