我试图为插入SQL编写prepare语句,并且它有很多行要一次插入。所以目前的准备声明如下,
my $sth = $dbh->prepare("INSERT INTO queues_details (id,keyword,data,flags) VALUES
(?,'penaltymemberslimit','0','0'),
(?,'answered_elsewhere','0','0'),
(?,'timeoutpriority','app','0'),
(?,'timeoutrestart','no','0'),
(?,'memberdelay','0','0'),
(?,'servicelevel','60','0'),
(?,'reportholdtime','no','0'),
(?,'ringinuse','yes','0'),
(?,'weight','0','0'),
(?,'autofill','no','0'),
(?,'eventmemberstatus','no','0'),
(?,'eventwhencalled','no','0'),
(?,'monitor-join','yes','0'),
(?,'monitor-format','','0'),
(?,'periodic-announce-frequency','0','0'),
(?,'queue-thankyou','queue-thankyou','0'),
(?,'queue-callswaiting','queue-callswaiting','0'),
(?,'queue-thereare','queue-thereare','0'),
(?,'maxlen','0','0'),
(?,'joinempty','yes','0'),
(?,'leavewhenempty','no','0'),
(?,'strategy','ringall','0'),
(?,'timeout','15','0'),
(?,'retry','5','0'),
(?,'wrapuptime','0','0'),
(?,'announce-frequency','60','0'),
(?,'announce-holdtime','no','0'),
(?,'announce-position','yes','0'),
(?,'queue-youarenext','queue-youarenext','0');");
请注意,所有?
值都是相同的ID。
这很难维护,很难添加/删除prepare
和execute
中的行。
这些占位符(?s)是否有任何编号方法,因此我可以轻松找到需要更改的行。
谢谢!
答案 0 :(得分:6)
仅使用占位符
my $sql = "INSERT INTO queues_detail (id,keyword,data,flags) VALUES ";
$sql .= join ', ', ("(?,?,?,?)") x @data;
$dbh->do($sql, $undef, map { $id, @$_ } @data);
或者根本不使用任何
my $sql = "INSERT INTO queues_detail (id,keyword,data,flags) VALUES ";
$sql .= join(', ', map { "(" . join(', ', map $dbh->quote($_), $id, @$_) . ")" } @data);
$dbh->do($sql);
以上使用以下内容:
my @data = (
[ 'penaltymemberslimit', '0', 0 ],
[ 'answered_elsewhere', '0', 0 ],
[ 'timeoutpriority', 'app', 0 ],
[ 'timeoutrestart', 'no', 0 ],
[ 'memberdelay', '0', 0 ],
[ 'servicelevel', '60', 0 ],
[ 'reportholdtime', 'no', 0 ],
[ 'ringinuse', 'yes', 0 ],
[ 'weight', '0', 0 ],
[ 'autofill', 'no', 0 ],
[ 'eventmemberstatus', 'no', 0 ],
[ 'eventwhencalled', 'no', 0 ],
[ 'monitor-join', 'yes', 0 ],
[ 'monitor-format', '', 0 ],
[ 'periodic-announce-frequency', '0', 0 ],
[ 'queue-thankyou', 'queue-thankyou', 0 ],
[ 'queue-callswaiting', 'queue-callswaiting', 0 ],
[ 'queue-thereare', 'queue-thereare', 0 ],
[ 'maxlen', '0', 0 ],
[ 'joinempty', 'yes', 0 ],
[ 'leavewhenempty', 'no', 0 ],
[ 'strategy', 'ringall', 0 ],
[ 'timeout', '15', 0 ],
[ 'retry', '5', 0 ],
[ 'wrapuptime', '0', 0 ],
[ 'announce-frequency', '60', 0 ],
[ 'announce-holdtime', 'no', 0 ],
[ 'announce-position', 'yes', 0 ],
[ 'queue-youarenext', 'queue-youarenext', 0 ],
);
答案 1 :(得分:4)
由数据库驱动程序决定。其中一些支持其他占位符格式,但大多数不支持。您可以查看您的文档(例如DBD :: Pg,DBD :: mysql)并查看可用的文档。
您更好的选择是:
1:编写代码以生成SQL。你最好使用所有占位符;那么你可以从像
这样的结构开始my @data = (
[ $foo, 'penaltymemberslimit', 0, 0],
[ $bar, 'answered_elsewhere', 0, 0],
# ... a bunch more rows
);
并用以下内容跟进:
my $sql = "INSERT INTO queues_details (id,keyword,data,flags) VALUES";
my @binds;
for my $row (@data) {
$sql .= " (?,?,?,?)";
push @binds, @$row;
}
my $sth = $dbh->prepare($sql);
$dbh->execute(@binds);
2:使用DBIx::Class。如果您为queues_details
表创建一个包含类的模式,那么您可以创建一个大的哈希数组,其列名为键,值为值,并将其传递给populate
,DBIC将为你写插入。它甚至可以使用更有效的方式插入批量数据,例如使用特殊API或延迟约束。您还可以选择创建对象并在其上调用create
。