gpt4 book ai didi

perl - 如何告诉 DBD::CSV 使用逗号作为小数点分隔符?

转载 作者:行者123 更新时间:2023-12-04 22:14:19 25 4
gpt4 key购买 nike

我正在尝试使用带有 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 中的数据,它是一个中间有逗号的浮点值,如一个 float 。相反,它将列视为整数,因为它不理解逗号。

以下是一些示例数据:
foo;foo;81,90
bar;bar;80,50
baz;baz;80,70

因此,带有此数据的上述代码将产生一行输出: 81,90 。当然,这是错误的。它使用 int()col3 部分进行比较,这是正确的,但不是我想要的。

问题: 我怎么能告诉它把带逗号的数字当作浮点数?

我想过的事情:
  • 我没有在 Text::CSV 中找到任何内置方法来做到这一点。我不确定在 Text::CSV 中的哪个位置我可以将它连接起来,或者 Text::CSV 中是否有一种机制可以将这些东西放入其中。
  • 不知道有没有问题,如果可能,DBD::CSV 想使用 Text::CSV_XS。
  • 也许我可以稍后再做,在数据被读取并且已经存储在某处之后,但我还不确定正确的接入点在哪里。
  • 我知道这些东西存储在 SQL::Statement 中。我还不知道在哪里。不知何故,这可能很方便。

  • 将源 CSV 文件更改为点而不是逗号是 而不是 一个选项。

    我愿意接受各种建议。也欢迎通过 SQL 来处理整个 CSV 的其他方法。非常感谢。

    最佳答案

    您需要使用 SQL::Statement::Functions (已作为 DBD::CSV 的一部分加载)编写用户定义的函数。

    这个程序做你想要的。将 0.0 添加到转换后的字符串是完全没有必要的,但它说明了子例程的目的。 (还要注意 f_encoding 调用的 connect 参数中的拼写错误。)

    use strict;
    use warnings;

    use DBI;

    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 => 'test.csv',
    #skip_first_row => 0,
    col_names => [ map { "col$_" } (1..3) ], # see annotation below
    },
    },
    },
    ) or croak $DBI::errstr;

    $dbh->do('CREATE FUNCTION comma_float EXTERNAL');

    sub comma_float {
    my ($self, $sth, $n) = @_;
    $n =~ tr/,/./;
    return $n + 0.0;
    }

    my $sth = $dbh->prepare(
    'SELECT col3 FROM foo WHERE comma_float(col3) > 80.50 ORDER BY col3 ASC'
    );
    $sth->execute;

    while (my $res = $sth->fetchrow_hashref) {
    say $res->{col3};
    }

    输出
    80,70
    81,90

    关于perl - 如何告诉 DBD::CSV 使用逗号作为小数点分隔符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13743409/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com