我正在使用Perl DBD :: ODBC连接到一个Informix数据库,我以前对它的架构视而不见。我通过查询tabname和colname表成功发现了模式。我现在正在迭代这些表中的每一个,提取其中的所有内容以加载到另一个模型中。我发现的是null列从select查询中解脱出来。例如。如果一个表看起来像这样,有一个可选的空lastseen
列(任何数据类型):
ID username lastseen
-- -------- --------
1 joe 1234567890
2 bob 1098765432
3 mary
4 jane 1246803579
然后select * from mytable
(或单独指定所有列名称)停在 mary 行。
我的确使用NVL,如下所示:
select nvl(id, ''), nvl(username, ''), nvl(lastseen, '') from mytable
那好的,但是我的问题是:是否有更简单的Informix语法允许空值进入我的结果集,这很简单NULLS OK
或我遗失的东西?或者,一些数据库句柄选项允许相同的吗?
以下是我的Perl与nvl()hack的示例,如果相关的话:
my %tables = (
users => [
qw(id username lastseen)
]
);
foreach my $tbl (sort keys %tables) {
my $sql = 'select ' . join(',', map { "nvl($_, '')" } @{$tables{$tbl}}) . " from $tbl";
# sql like: select nvl(a, ''), nvl(b, ''), ...
my $sth = $dbh->prepare($sql);
$sth->execute;
while(defined(my $row = $sth->fetchrow_arrayref)) {
# do ETL stuff with $row
}
}
答案 0 :(得分:0)
在尝试安装DBD :: Informix后,我回过头来发现,由于某种原因,在数据库句柄上启用LongTruncOk
确实允许选择所有行,包括那些具有空列的行。我不认为这是问题的根源,但它在这里起作用。
然而,这个解决方案似乎与对语言环境的无关调整相冲突,以支持非ascii字符。我将DB_LOCALE=en_us.utf8
和CLIENT_LOCALE=en_us.utf8
添加到我的连接字符串中,以防止在遇到非ascii字符时(例如,在500的结果集中,其中第300行具有非ascii字符时)不会返回尾随的200行)。通过这种方式设置语言环境以及在dbh上启用LongTruncOk
所有行都被返回(没有NVL
hack),但是空列的前导行添加了字节,而不是任何模式这对我来说很明显。当我将语言环境设置从连接字符串中删除并设置LongTruncOk
时,正确选择了具有空列的行,但是具有utf字符的行会中断。
因此,如果您没有charset问题,或许只有LongTruncOk
对您有用。出于我的目的,我不得不继续使用NVL
解决方法来处理空值并指定字符的区域设置。
答案 1 :(得分:-1)
检查this - Perl中的NULL部分。似乎有了这个驱动程序,没有简单的方法来处理这个问题。