简体   繁体   English

Perl DBI占位符,而不是?s

[英]Perl DBI placeholders other than ?s

I'm trying to write prepare statement for insert SQL and it have many rows to insert at once. 我正在尝试为插入SQL编写prepare语句,它一次要插入许多行。 So current prepare statement is like below, 因此,当前的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');");

Note that all the ? 注意所有? values will be same id. 值将是相同的ID。

This is complex to maintain and hard to add/remove rows from prepare and execute . 这维护起来很复杂,并且很难从prepareexecute添加/删除行。 Is there any kind of numbering method for these placeholders (?s) so I can easily find the rows I need to change. 这些占位符(?s)是否有任何编号方法,因此我可以轻松找到需要更改的行。

Thank you! 谢谢!

Use only placeholders 仅使用占位符

my $sql = "INSERT INTO queues_detail (id,keyword,data,flags) VALUES ";
$sql .= join ', ', ("(?,?,?,?)") x @data;

$dbh->do($sql, $undef, map { $id, @$_ } @data);

Or don't use any at all 或完全不使用

my $sql = "INSERT INTO queues_detail (id,keyword,data,flags) VALUES ";
$sql .= join(', ', map { "(" . join(', ', map $dbh->quote($_), $id, @$_) . ")" } @data);

$dbh->do($sql);

The above use the following: 上面使用以下内容:

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 ],
);

It's up to the database driver. 这取决于数据库驱动程序。 Some of them support other placeholder formats, but most don't. 其中一些支持其他占位符格式,但大多数不支持。 You can look at the docs for yours (eg DBD::Pg, DBD::mysql) and see what's available. 您可以查看自己的文档(例如DBD :: Pg,DBD :: mysql),然后查看可用的文档。

Your better options are: 您更好的选择是:

1: Write code to generate the SQL. 1:编写代码以生成SQL。 You're best off using all placeholders; 最好使用所有占位符。 then you can start off with a structure like 那么您可以从一个类似的结构开始

my @data = (
    [ $foo, 'penaltymemberslimit', 0, 0],
    [ $bar, 'answered_elsewhere', 0, 0],
    # ... a bunch more rows
);

and follow it up with something like: 并遵循以下步骤:

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: Use DBIx::Class . 2:使用DBIx :: Class If you create a schema with a class for your queues_details table, then you can just create one big array of hashes with column names as keys and values as values, and pass that to populate , and DBIC will write the insert for you. 如果您为queues_details表创建一个带有类的模式,那么您就可以创建一个大型的哈希数组,将列名作为键,将值作为值,并将其传递给populate ,DBIC将为您编写插入。 It might even use a more efficient way of inserting bulk data, for example using a special API or deferring constraints. 它甚至可以使用更高效的方式来插入批量数据,例如使用特殊的API或推迟约束。 You also have the option of creating objects and calling create on them. 您还可以选择创建对象并在其上调用create

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM