2010-05-18 37 views
5

我有一個Perl腳本根據管道分隔文本文件將數據插入到Postgres中。有時,一個字段爲空(按預期)。但是,Perl會將此字段設置爲空字符串,並且Postgres插入語句失敗。如何在Perl的DBD :: Pg中插入空字段?

下面是一個代碼片段:


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是一個可爲空的整型數據類型。

+0

此代碼工作在這裏,Perl的5.10.1,DBD :: PG 2.15.1 ,Postgres 8.4。另外你爲什麼使用SELECT?,?而不是VALUES(?,?)? – MkV 2010-05-18 17:46:46

+0

另外,使用嚴格;使用警告; 並修復你的變量聲明 – MkV 2010-05-18 17:51:42

+0

關於SQL格式..真正的代碼實際上有一些連接選擇。 – User1 2010-05-18 19:47:22

回答

4

我不知道你是否測試你粘貼代碼和數據一起,他們用Perl 5.10.1,DBD :: PG 2.15.1和Postgres 8.4工作。你也應該使用strict和warnings,而不是依賴你的變量的包範圍。

如果您更改您的代碼和數據以使用三個或更多個字段,而讓非終端一個爲空,則可以從DBD :: Pg觸發該錯誤。執行準備好的語句之前像這樣的行添加到您的代碼:

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

要@field空字符串映射到民主基金

+0

負責將空字符串轉換爲空值。奇怪的是,刪除輸入中的字段導致空字符串變爲空(至少看起來發生了什麼)。 – User1 2010-05-18 19:41:24

+0

foreach在這裏會更具可讀性 – 2010-05-19 07:44:17

+0

如果一個字符串以您所分割的字符結尾,如'a | 4 |'那麼最終的數組元素根本就沒有被填充,沒有變成空字符串,所以它是undef,參見perldoc -f split。 – MkV 2010-05-19 09:54:19

0

undef通常映射到NULL。看起來你插入的空字符串與undef不一樣。

+0

您測試了代碼?只有兩個字段? – MkV 2010-05-18 18:03:00

2

該DBI包映射undefNULL。 (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

你如果永遠不是真的,如果你把嚴格的使用;使用警告;在你的代碼中,你會得到'使用未初始化值$ field [1]'的字符串eq' – MkV 2010-05-18 17:53:23

+1

@james,我不確定你的意思。它可以在'strict'和'warnings'啓用並且條件成功的情況下正常工作。'perl -Mstrict -Mwarnings -MData :: Dumper -le'my $ str =「a | b || d」;我的@a = split/\ | /,$ str; if($ a [2] eq「」){$ a [2] = undef; };打印Dumper \ @ a'' – friedo 2010-05-18 19:02:00

+0

它現在可以工作,但由於問題最初出現了(並且如您所回答的那樣),因此只有2個字段,空字段在最後,返回該索引的undef。 – MkV 2010-05-19 09:56:53

相關問題