Как вставить пустые поля с помощью Perl DBD :: Pg? - PullRequest
5 голосов
/ 18 мая 2010

У меня есть скрипт 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 является типом целочисленного типа, допускающим обнуление.

Ответы [ 3 ]

4 голосов
/ 18 мая 2010

Я не уверен, что вы проверяли, вставлены ли ваш код и данные вместе, они работают с Perl 5.10.1, DBD :: Pg 2.15.1 и Postgres 8.4. Также вы должны использовать строгие и предупреждения и не полагаться на объем пакета для ваших переменных.

Если вы измените свой код и данные на использование трех или более полей, оставив нетерминальное поле пустым, вы можете вызвать ошибку с помощью DBD :: Pg. Добавьте следующую строку в ваш код перед выполнением подготовленного оператора:

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

Чтобы отобразить пустые строки в @field для undef

2 голосов
/ 18 мая 2010

Пакет 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]);
}
0 голосов
/ 18 мая 2010

undef обычно отображается в NULL. Похоже, вы вставляете пустую строку, которая не совпадает с undef.

...