【发布时间】:2012-11-24 11:16:34
【问题描述】:
我正在尝试使用带有 DBI 和 DBD::CSV 的德式 CSV 文件。这反过来又使用Text::CSV 来解析文件。我想使用 SQL 查询该文件中的数据。
让我们先看一下文件。用分号(;)隔开,里面的数字是这样的:5,23,相当于英文的5.23。
这是我目前所得到的:
use strict; use warnings;
use DBI;
# create the database handle
my $dbh = DBI->connect(
'dbi:CSV:',
undef, undef,
{
f_dir => '.',
f_schema => undef,
f_ext => '.csv',
f_encoding => 'latin-1',
csv_eol => "\n",
csv_sep_char => ';',
csv_tables => {
foo => {
file => 'foo.csv',
#skip_first_row => 0,
col_names => [ map { "col$_" } (1..3) ], # see annotation below
},
},
},
) or croak $DBI::errstr;
my $sth = $dbh->prepare(
'SELECT col3 FROM foo WHERE col3 > 80.50 ORDER BY col3 ASC'
);
$sth->execute;
while (my $res = $sth->fetchrow_hashref) {
say $res->{col3};
}
现在,这看起来很不错。问题是 SQL(意思是 SQL::Statement,它位于 DBI 和 DBD::CSV 后面的某个位置)不考虑 col3 中的数据,这是一个中间带逗号的浮点值, 作为一个浮点数。相反,它将列视为整数,因为它不理解逗号。
以下是一些示例数据:
foo;foo;81,90
bar;bar;80,50
baz;baz;80,70
所以上面的代码和这个数据会产生一行输出:81,90。当然,这是错误的。它使用col3 的int() 部分进行比较,这是正确的,但不是我想要的。
问题:如何告诉它把带逗号的数字视为浮点数?
我想到的事情:
- 我没有在 Text::CSV 中找到任何内置方法来执行此操作。我不确定在 Text::CSV 中的哪个位置可以将其挂钩,或者 Text::CSV 中是否有机制可以将这些东西放入其中。
- 不知道DBD::CSV想尽可能使用Text::CSV_XS是否会造成问题。
- 也许我可以稍后再做,在读取数据并且已经存储在某个地方之后,但我还不确定正确的访问点在哪里。
- 我知道这些内容存储在 SQL::Statement 中。我还不知道在哪里。这可能会很方便。
将源 CSV 文件更改为使用点而不是逗号是不是一种选择。
我愿意接受各种建议。也欢迎通过 SQL 处理整个 CSV 的其他方法。非常感谢。
【问题讨论】:
-
您绝对需要通过 SQL 访问这些数据吗?
-
你说的这个“它”是谁? “它不理解逗号”,“它使用了 col3 的 int() 部分”...... Perl?一个模块?数据库?
-
@Borodin 的总体思路是拥有多个数据源。我们正在尝试将 CSV 文件从
opening 和<>ing 升级到基于 DB 的方法,其中 DB 将是 mysql 或 sqlite。第一步应该是构建 SQL,但使用 CSV 文件。我们不想破坏 CSV 文件涉及的其他进程。所以,是的,我想用 SQL 来做。 -
@TLP 这将是一些涉及执行查询的模块。可能在 DBI 中。目标是让该查询发挥作用。
-
@simbabque 也许可以通过使用小数点的德语区域设置以某种方式完成? POSIX 模块?