【问题标题】:How do I insert values from a hash into a database using Perl's DBI module?如何使用 Perl 的 DBI 模块将值从散列插入数据库?
【发布时间】:2017-04-28 03:31:42
【问题描述】:

我需要将哈希值插入数据库。以下是我必须在 table1 列 keyvalue 中插入值的代码模板:

use DBI;
use strict;

%hash; #assuming it already contains desired values
my $dbh = DBI->connect(
      "dbi:Sybase:server=$Srv;database=$Db", 
      "$user", "$passwd"
) or die sprintf 'could not connect to database %s', DBI->errstr;
my $query= "Insert INTO table1(key, values) VALUES (?,?) ";
my $sth = $dbh->prepare($query) 
    or die "could not prepare statement\n", $dbh->errstr;
$sth-> execute or die "could not execute", $sth->errstr; 

我知道如何使用数组插入值,即使用execute_array(),但不知道如何在table1 中插入%hash 中存在的值。

有什么建议吗?

【问题讨论】:

  • %hash 究竟包含什么?
  • 这有什么关系?它的定义与哈希的定义方式完全相同。
  • 哈希的结构是问题的重要组成部分。您已经有两个不同的答案,来自对问题的不同理解的人,因为不清楚哈希中的内容。
  • %hash 定义为 $key,$value。
  • 您的回答非常没有有帮助,这让我想知道您为什么拒绝向我们提供这些信息。您确实意识到$value 可能只是随便什么?

标签: perl dbi


【解决方案1】:

以下使用您的问题中提到的execute_array 函数。我测试了它。

my $dbh = DBI->connect("DBI:mysql:database=$DB;host=$host;port=$port", $user, $password);

my %hash = (
            1   =>  'A',
            2   =>  'B',
            0   =>  'C',
            );

my @keys = keys %hash;

my @values = values %hash;

my $sth = $dbh->prepare("INSERT INTO table1(id, value) VALUES (?,?);");

$sth->execute_array({},\@keys, \@values);

(抱歉,我没有可使用的 Sybase 数据库,否则我将使用它作为示例。)

【讨论】:

    【解决方案2】:

    试试SQL::Abstract

    use DBI;
    use SQL::Abstract;
    use strict;
    
    %hash; #assuming it already contains desired values
    my $dbh = DBI->connect(
          "dbi:Sybase:server=$Srv;database=$Db", 
          "$user", "$passwd"
    ) or die sprintf 'could not connect to database %s', DBI->errstr;
    
    my ($query, @bind) = $sql->insert("tableName", \%hash);
    my $sth = $dbh->prepare($query) 
        or die "could not prepare statement\n", $dbh->errstr;
    $sth-> execute (@bind) or die "could not execute", $sth->errstr;
    

    【讨论】:

      【解决方案3】:

      这是构建查询的最简单的方法。我通常会这样做,因为我还没有找到其他解决方法。

      use strict;
      use DBI;
      
      my $dbh = Custom::Module::Make::DBH->connect('$db');
      
      my %hash = (
          apple  => 'red',
          grape  => 'purple',
          banana => 'yellow',
      );
      
      my $keystr = (join ",\n        ", (keys %hash));
      my $valstr = join ', ', (split(/ /, "? " x (scalar(values %hash))));
      my @values = values %hash;
      
      my $query = qq`
          INSERT INTO table1 (
              $keystr
          )
          VALUES (
              $valstr
          )
      `;
      
      my $sth = $dbh->prepare($query) 
          or die "Can't prepare insert: ".$dbh->errstr()."\n";
      
      $sth->execute(@values)
          or die "Can't execute insert: ".$dbh->errstr()."\n";
      

      但有可能我也没有正确理解这个问题:P

      【讨论】:

      • 我看到这种方法的问题是人们可能会陷入没有正确转义参数的陷阱。我总是建议使用占位符!除此之外,好主意。
      • 啊,感谢您指出这一点。我刚刚对解决该问题的上述代码进行了更新。很抱歉错过了。
      • 对不起,如果这是一个愚蠢的问题,但 Custom::Module::Make:: 应该根据您的 DBH 的位置进行更改,对吗?
      【解决方案4】:

      也许你可以尝试使用

      for my $key (keys %hash) {
        $sth->execute($key, $hash{$key}) or die $sth->errstr;
      }
      

      这是你想要达到的目标吗?

      如果我正确理解manual(“通过传递的引用为每个参数元组(值组)[...]执行一次准备好的语句...”)也应该可以简单地

      ($tuples, $rows) = $sth->execute_array(\%hash) or die $sth->errstr;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-17
        • 1970-01-01
        • 2010-09-27
        • 1970-01-01
        • 2017-05-17
        相关资源
        最近更新 更多