除了?s之外的Perl DBI占位符

时间:2015-05-26 03:57:50

标签: sql perl placeholder dbi

我试图为插入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。

这很难维护,很难添加/删除prepareexecute中的行。 这些占位符(?s)是否有任何编号方法,因此我可以轻松找到需要更改的行。

谢谢!

2 个答案:

答案 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

相关问题