从包含一些空列的 Informix 表中选择所有行
Posted
技术标签:
【中文标题】从包含一些空列的 Informix 表中选择所有行【英文标题】:Selecting all rows from Informix table containing some null columns 【发布时间】:2015-05-28 17:50:18 【问题描述】:我正在使用 Perl DBD::ODBC 连接到一个 Informix 数据库,我以前对它的架构视而不见。我已经通过查询 tabname 和 colname 表成功地发现了架构。我现在遍历每个表,提取其中的所有内容以加载到另一个模型中。我发现空列退出了选择查询。例如。如果一个表看起来像这样,带有一个可选的 null 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
【问题讨论】:
这真的没有必要。当然 DBD::Informix 可以正确处理 NULL 值 - 你有充分的理由不能使用那个驱动程序而不是 ODBC 驱动程序吗? 半好,只是我处于一个非常庞大且偏执的企业环境中,安装新模块实际上是一个巨大的痛苦,可能不值得为这个有限的应用程序付出努力,因为我确实有一种解决方法。我们还有其他解决方案类似地使用 ODBC 来抽象数据库层,所以我当然有兴趣了解它的局限性和怪癖,如果这确实是罪魁祸首(我非常愿意相信它是)。 【参考方案1】:在安装 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 字符的行会中断。
因此,如果您没有字符集问题,也许 LongTruncOk
对您有用。出于我的目的,我不得不继续使用NVL
解决方法来处理空值并指定字符的语言环境。
【讨论】:
【参考方案2】:检查this - Perl 中的 NULL 部分。看来有了这个驱动就没有简单的办法来处理这个问题了。
【讨论】:
以上是关于从包含一些空列的 Informix 表中选择所有行的主要内容,如果未能解决你的问题,请参考以下文章