プレースホルダを利用したバルクインサートは、sqlでは次のように記載します。
insert into tbl_meisai (mitsumori_id, hinmei, hinban, quantity, tanka,price) values (?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?),(?,?,?,?,?)...
これをperl(DBI)で書くなら、次のようになるかと思います。
#無制限に大量レコードをinsertすると、sql文長の制限を超える気がする為 my $BULK_INSERT_LIMIT = 40; #明細行に登録されるカラム名 my @FORM_KEYS_MEISAI = qw/maker maker_id shouhin_code hinmei_code hinmei hinban color size juchuu_quantity unit juchuu_tanka juchuu_price note/; sub add_hachuu_meisai { my ($self,$meisais) = @_; return $self if(scalar(@$meisais)==0); my @meisais_grp; my $row_id = 1; my $pre_page_id = 1; for my $meisai (@$meisais){ #row_idはpage毎にcountします $row_id = 1 if $meisai->{page_id} != $pre_page_id; $pre_page_id = $meisai->{page_id}; push(@meisais_grp,$meisai); if($meisai->{page_id} != $pre_page_id or scalar(@meisais_grp)>$BULK_INSERT_LIMIT ){ #この単位(かたまり)でbulk inset $row_id = $self->_add_meisai_page_each($meisai->{page_id}, $row_id, \@meisais_grp); return undef unless($row_id); @meisais_grp = (); } } if( scalar(@meisais_grp)>0 ){ my $page_id = $meisais_grp[0]->{page_id}; #この単位(かたまり)でbulk inset $row_id = $self->_add_meisai_page_each($page_id, $row_id, \@meisais_grp); return undef unless($row_id); } return $self; } sub _add_meisai_page_each { my ($self,$pno,$row_id,$meisais) = @_; return $self if(scalar(@$meisais)==0); my $keys_str = join(',',@FORM_KEYS_MEISAI); my $vals_str = '(?,?,?'. ',?'x scalar(@FORM_KEYS_MEISAI) .')'; my @meisais_val; for my $meisai (@$meisais){ push(@meisais_val,$vals_str); } my $meisais_val_str = join(',',@meisais_val); my $sql =<<EOF; insert into h_meisai (hachuu_id,page_id,row_id,$keys_str) values $meisais_val_str EOF my $sth = $self->{dbh}->prepare($sql); my @vals_all; for my $meisai (@$meisais){ my @vals_row = ($self->{id},$pno,$row_id++); for my $meisai_key ( @FORM_KEYS_MEISAI ){ push(@vals_row,$meisai->{$meisai_key}); } push(@vals_all,@vals_row); } unless ( $sth->execute(@vals_all) ){ $self->error( $sth->errstr ); $self->set_err_msg( $sth->errstr ); return undef; } return $row_id; }