僕はDBMSというとPostgreSQLを主に使っているのですが、このPostgreSQL、バージョン間で互換性のない変更点というのが結構あって、これを知らないと、データベースの移行作業とか、テストサーバで開発したものを本番サーバにアップしようとか言うときに、この違いのせいでトラブるなんてことになりかねません。
「pg_atoi: zero-length string」なんていうエラーもほとんどが7.2から7.3への互換性のない変更点に書かれている、
整数型の読み込みで、空文字列が禁止されました。 この結果、整数型フィールドに対し、COPY 文での入力フィールドの空指定や VALUES 句での空文字列 '' 指定などで、0 入力とはならず、エラーとなります。
が原因でしょう。
例として、名前と年齢をフォームから入力させて裏でDBに保存するようなWebアプリケーションを考えてみましょう。
名前と年齢を保存しておくテーブルを次のように定義します。
CREATE TABLE user_master(
name text,
age int
);
そしてこのDBにデータを保存するためのPerlスクリプトを次のように書いたとしましょう。
#! /usr/local/bin/perl
use strict;
use warnings;
use CGI;
use DBI;
my $query = CGI->new;
my $dbh = DBI->connect('dbi:Pg:dbname=testdb', 'username','passwd');
my $name = $query->param('name');
my $age = $query->param('age')
$dbh->do("INSERT INTO user_master (name,age) values(?,?)",$name,$age);
このスクリプトは7.2では問題なく動きますが、7.3だとエラーになる可能性があります。
エラーになるのはageに値が入力されなかった場合です。いつからだったか忘れてしまいましたが、(2.7xくらいからだったような。。)CGI.pmではparam('key')の値が空だった場合、空文字列を返すので、もしageの値が空だと$ageには空文字列が代入されます。それをそのままPostgreSQLのint型のカラムに入れようとしているので、pg_atoi: zero-length string」というエラーがでてしまうわけです。このエラーを回避するために修正したスクリプトは以下のようになります。
#! /usr/local/bin/perl
use strict;
use warnings;
use CGI;
use DBI;
my $query = CGI->new;
my $dbh = DBI->connect('dbi:Pg:dbname=testdb', 'username','passwd');
my $name = $query->param('name') || undef;
my $age = $query->param('age') || undef;
$dbh->do("INSERT INTO user_master (name,age) values(?,?)",$name,$age);
param('key')の値が偽だった場合(空文字も偽になります)、undefを代入するようにしました。入力データが多い場合は、mapを使って一括処理してやるのが効率的でしょう。
my @keys = qw(name age kana birth_year birth_month birth_day);
my %params = map {$_ => $query->param($_) ? $query->param($_) : undef} @keys;
my $age = $query->param('age') || undef;
返信削除だと、0歳の人も null になってしまいます。
そうですね(汗
返信削除このアプリケーションは0歳の人の登録を受け付けないと言うことで許してください(苦笑)
0歳がnullにならないようにするにはこうしないといけませんね。
my $age = $query->param('age');
$age = undef if $age eq '';