Sql 除?s以外的Perl DBI占位符
我正在尝试为insert SQL编写prepare语句,它一次要插入许多行。所以当前的prepare语句如下所示Sql 除?s以外的Perl DBI占位符,sql,perl,placeholder,dbi,Sql,Perl,Placeholder,Dbi,我正在尝试为insert SQL编写prepare语句,它一次要插入许多行。所以当前的prepare语句如下所示 my $sth = $dbh->prepare("INSERT INTO queues_details (id,keyword,data,flags) VALUES (?,'penaltymemberslimit','0','0'), (?,'answered_
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中添加/删除行。
这些占位符是否有任何类型的编号方法,以便我可以轻松找到需要更改的行
谢谢大家! 这取决于数据库驱动程序。其中一些支持其他占位符格式,但大多数不支持。您可以查看自己的文档,例如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:使用。如果为queues\u details表创建一个带有类的模式,那么您只需创建一个大的哈希数组,将列名作为键,值作为值,并将其传递给populate,DBIC就会为您编写insert。它甚至可以使用更有效的方法插入批量数据,例如使用特殊的API或延迟约束。您还可以选择创建对象并对其调用create。这取决于数据库驱动程序。其中一些支持其他占位符格式,但大多数不支持。您可以查看自己的文档,例如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:使用。如果为queues\u details表创建一个带有类的模式,那么您只需创建一个大的哈希数组,将列名作为键,值作为值,并将其传递给populate,DBIC就会为您编写insert。它甚至可以使用更有效的方法插入批量数据,例如使用特殊的API或延迟约束。您还可以选择创建对象并对其调用create。仅使用占位符
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 ],
);
仅使用占位符
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 ],
);
即使没有占位符,插入也会非常笨拙。您真的在脚本中使用不同的ID值集多次执行此查询吗?目前,一次只能执行一个ID值。即使没有占位符,插入也会非常麻烦。您真的在脚本中使用不同的ID值集多次执行此查询吗?目前一次只能执行一个ID值。您生成的SQL语句缺少很多逗号。您生成的SQL语句缺少很多逗号。很好的解决方案,谢谢!事实上,一次只会有一个id,忘记在问题中提及。我还为此阅读了bind_uParam。这允许简化解决方案,尽管只是一点点。更新答案。很好的解决方案,谢谢!事实上,一次只会有一个id,忘记在问题中提及。我还为此阅读了bind_uParam。这允许简化解决方案,尽管只是一点点。更新答案。