代码之家  ›  专栏  ›  技术社区  ›  User1

如何用Perl的dbd::pg插入空字段?

  •  5
  • User1  · 技术社区  · 14 年前

    我有一个Perl脚本,根据管道分隔的文本文件将数据插入Postgres。有时,字段为空(如预期)。但是,Perl将此字段变为空字符串,Postgres插入语句失败。

    下面是一段代码:

    
    use DBI;
    
    #Connect to the database.
    $dbh=DBI->connect('dbi:Pg:dbname=mydb','mydb','mydb',{AutoCommit=>1,RaiseError=>1,PrintError=>1});
    
    #Prepare an insert.
    $sth=$dbh->prepare("INSERT INTO mytable (field0,field1) SELECT ?,?");
    
    while (<>){
        #Remove the whitespace
        chomp;
    
        #Parse the fields.
        @field=split(/\|/,$_);
    
        print "$_\n";
    
        #Do the insert.
        $sth->execute($field[0],$field[1]);
    }
    

    如果输入是:

    a|1
    b|
    c|3
    

    编辑:使用这个输入。

    a|1|x
    b||x
    c|3|x
    

    它会失败 b| .

    DBD::Pg::st execute failed: ERROR:  invalid input syntax for integer: ""

    我只希望它在field1上插入一个空值。有什么想法吗?

    编辑:我在最后一分钟简化了输入。旧的输入实际上使它工作是有原因的。所以现在我把输入改成了会使程序失败的东西。还要注意,field1是一个可以为空的integer数据类型。

    3 回复  |  直到 14 年前
        1
  •  4
  •   MkV    14 年前

    我不确定您是否测试了将代码和数据粘贴在一起,它们与Perl5.10.1、DBD::pg 2.15.1和Postgres8.4一起工作。此外,您应该使用严格的和警告,而不是依赖包范围作为变量。

    如果将代码和数据更改为使用三个或更多字段,而非终端字段为空,则可以从dbd::pg触发错误。在执行准备好的语句之前,请在代码中添加这样的行:

    map { $_ eq '' and $_ = undef } @field;
    

    将@field中的空字符串映射到undef

        2
  •  2
  •   friedo    14 年前

    DBI包映射 undef NULL . (Perl的定义性与错误性逻辑实际上非常适合SQL的三元逻辑。)

    所以,在你的 while 循环,只需检查指示字段是否为空字符串,如果是,则使其成为空字符串。 解脱 而是:

    while (<>){
        ...
        #Parse the fields.
        @field=split(/\|/,$_);
    
        if ( $field[1] eq '' ) { 
            # handle NULLs
            $field[1] = undef;
        }
    
        #Do the insert.
        $sth->execute($field[0],$field[1]);
    }
    
        3
  •  0
  •   David M    14 年前

    undef 通常映射为空。看起来您插入的空字符串与 解脱 .