如何使用Perl的DBD :: Pg插入空字段?

时间:2010-05-18 16:44:59

标签: perl postgresql dbi

我有一个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上插入null。有什么想法吗?

编辑:我在最后一分钟简化了输入。旧的输入实际上由于某种原因使它工作。所以现在我将输入改为使程序失败的东西。另请注意,field1是可以为空的整数数据类型。

3 个答案:

答案 0 :(得分:4)

我不确定您是否测试了粘贴的代码和数据,它们与Perl 5.10.1,DBD :: Pg 2.15.1和Postgres 8.4一起使用。此外,您应该使用严格和警告,而不是依赖于变量的包范围。

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

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

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

答案 1 :(得分:2)

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

因此,在while循环中,只需检查指示字段是否为空字符串,如果是,请改为undef

while (<>){
    ...
    #Parse the fields.
    @field=split(/\|/,$_);

    if ( $field[1] eq '' ) { 
        # handle NULLs
        $field[1] = undef;
    }

    #Do the insert.
    $sth->execute($field[0],$field[1]);
}

答案 2 :(得分:0)

undef通常映射为NULL。看起来您正在插入与undef不同的空字符串。