2015-08-19 62 views
2

我現在有代碼的Perl看起來像這樣:(從mobanswer帶到了前面的問題)Perl的許多插入statments到mysql數據庫

@valid = grep { defined($column_mapping{ $headers[$_] }) } 0 .. $#headers; 

... 

my $sql = sprintf 'INSERT INTO tablename (%s) VALUES (%s)', 
    join(',', map { $column_mapping{$_} } @headers[@valid]), 
    join(',', ('?') x scalar @valid); 
my $sth = $dbh->prepare($sql); 

... 

my @row = split /,/, <INPUT>; 
$sth->execute(@row[@valid]); 

這基本上是從csv數據動態構建一個sql插入語句,並且只允許選擇具有來自列映射的正確標題的csv數據。

我一直在尋找如何做一次插入數據與多行數據的例子。

我的perl腳本需要運行幾百萬個插入語句,並且一次只做一個,看起來確實很慢,尤其是因爲我運行它的服務器只有6g內存和慢速的Internet連接。

有沒有辦法可以一次上傳超過1行的數據?所以一個插入語句可能上傳50行,或100行?我無法找出如何與Perl DBI。

+0

的可能重複的[Perl的DBI插入使用的MySQL天然多重插入能力的多個行(http://stackoverflow.com/questions/8421711/perl-dbi-insert-multiple-rows-using-mysql-native-multiple-插入能力) – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot這是我找到的唯一一個,這傢伙建議一次只做一個,其他大多數評論都認爲,這不是我想要的。他說他不會使用這種方法來做多個插入語句,大多數答案都說一次只能做一個。我想知道是否有答案不是這樣 – Lain

+2

閱讀已接受答案中的第一種方法,從「您可以根據數組大小插入'(?,?,?)'多次」。這顯示瞭如何爲多行生成單個插入語句。 – ThisSuitIsBlackNot

回答

2
my $sql_values = join(' ', ('(?, ?, ?)') x scalar(@array)); 

正如前面所說的,那麼你可以將其壓平。

0

您可以使用與常規SQL相同的語法一次插入多行,但您需要使用Perl正確構建INSERT statemtent。 Perl的slice()可能會幫助您:

假設您有7行數據並希望將它們插入3行的塊中。 「定期」 SQL將會像這樣:

insert into T (col1, col2) values (1, 2), (3, 4), (5, 6); 
insert into T (col1, col2) values (7, 8), (9,10), (11,12); 
insert into T (col1, col2) values (13,14); 

讓我們假設你的Perl結構是這樣的:

my $values = [ [1,2], [3,4], ..., [13,14] ]; 

如果不是的話,把它變成了這種形狀。現在:

use constant CHUNKSIZE => 3; 

my $stmt = sprintf('insert into T (col1, col2) values %s', 
        join(',', '(?,?)' x CHUNKSIZE)); 
# $stmt is now 'insert into T (col1, col2) values (?,?),(?,?),(?,?)' 

my $sth = $dbh->prepare($stmt); 

while(my @chunk = splice(@{$values}, 0, CHUNKSIZE)) { 
    # @chunk has 3 elements (rows), or less for the last chunk 
    if (scalar @chunk == CHUNKSIZE) { 
     $sth->execute(@chunk); # inserts 3 rows at once 
    } else { 
     # build and prepare a new statement for the remaining rows. 
     # in our sample there is only 1 remaining row. 
     $stmt = sprintf('insert into T (col1, col2) values %s', 
         join(',', '(?,?)' x scalar @chunk)); 
     $sth = $dbh->prepare($stmt); 
     $sth->execute(@chunk); # inserts the last row 
    } 
}