1

このスクリプトでは、ファイル名拡張子に問題があります: /home/mm/test_x を使用すると動作しますが、/home/mm/test_x.csv という名前のファイルでは動作しません:

#!/usr/bin/env perl
use warnings; use strict;
use 5.012;
use DBI;

my $table_1 = '/home/mm/test_1.csv';
my $table_2 = '/home/mm/test_2.csv';
#$table_1 = '/home/mm/test_1';
#$table_2 = '/home/mm/test_2';

my $dbh = DBI->connect( "DBI:CSV:" );
$dbh->{RaiseError} = 1;

$table_1 = $dbh->quote_identifier( $table_1 );
$table_2 = $dbh->quote_identifier( $table_2 );

my $sth = $dbh->prepare( "SELECT a.id, a.name, b.city FROM $table_1 AS a NATURAL JOIN $table_2 AS b" );

$sth->execute;
$sth->dump_results;
$dbh->disconnect;

ファイル名拡張子付きの出力:

DBD::CSV::st 実行に失敗しました:
実行エラー: No such column '"/home/mm/test_1.csv".id' が /usr/local/lib/perl5/site_perl/5.12.0/x86_64-linux から呼び出されました/DBD/File.pm で 570。

ファイル名拡張子なしの出力:

'1', 'Brown', 'Laramie'
'2', 'Smith', 'Watertown'
2 行

これはバグですか?

猫のテスト_1.csv

ID、名前
1、ブラウン
2、スミス
5、グリーン

猫のテスト_2.csv

id、都市
1、ララミー
2、ウォータータウン
8、スプリングビル

4

3 に答える 3

3

DBD::CSV は、クエリで使用するテーブル名をファイル名にマップする方法を提供します。同じメカニズムを使用して、行末、フィールド区切りなどのファイルごとの属性を設定します。DBD::CSV ドキュメントで「csv_tables」を探してください。

#!/usr/bin/env perl

use warnings;
use strict;

use DBI;

my $dbh = DBI->connect("DBI:CSV:f_dir=/home/mm", { RaiseError => 1 });
$dbh->{csv_tables}->{table_1} = {
    'file' => 'test_1.csv',
    'eol' => "\n",
};
$dbh->{csv_tables}->{table_2} = {
    'file' => 'test_2.csv',
    'eol' => "\n",
};

my $sth = $dbh->prepare( "SELECT a.id, a.name, b.city FROM table_1 AS a NATURAL JOIN table_2 AS b" );

$sth->execute();
$sth->dump_results();
$dbh->disconnect();

私の場合、vi で CSV ファイルを作成したため、DBD::CSV はプラットフォームに関係なく DOS/Windows の行末を想定しているのに対し、vi で CSV ファイルを作成したため、行末文字を指定する必要がありました。

于 2010-05-08T05:15:51.837 に答える
0

これでもうまくいくようです:

#!/usr/bin/env perl
use warnings; use strict;
use 5.012;
use DBI;

my $dbh = DBI->connect("DBI:CSV:f_dir=/home/mm/Dokumente", undef, undef, { RaiseError => 1, });

my $table = 'new.csv';
$dbh->do( "DROP TABLE IF EXISTS $table" );
$dbh->do( "CREATE TABLE $table ( id INT, name CHAR(64), city CHAR(64) )" );
my $sth_new = $dbh->prepare( "INSERT INTO $table( id, name, city ) VALUES ( ?, ?, ? )" );

$dbh->{csv_tables}->{table_1} = { 'file' => '/tmp/test_1.csv', 'eol' => "\n", };
$dbh->{csv_tables}->{table_2} = { 'file' => '/tmp/test_2.csv', 'eol' => "\n", };
my $sth_old = $dbh->prepare( "SELECT a.id, a.name, b.city FROM table_1 AS a NATURAL JOIN table_2 AS b" );
$sth_old->execute();

while ( my $hash_ref = $sth_old->fetchrow_hashref() ) {
    state $count = 1;
    $sth_new->execute( $count++, $hash_ref->{'a.name'}, $hash_ref->{'b.city'} );
}
$dbh->disconnect();
于 2010-05-08T06:57:40.960 に答える
0

f_ext 属性と f_dir 属性を確認することをお勧めします。その後、テーブル名を csv なしで「test_1」および「test_2」として分類できますが、使用されるファイルは test_1.csv および test_2.csv になります。テーブル名のドットの問題は、通常、テーブル名からスキーマを分離するためにドットが使用されることです (f_schema を参照)。

于 2010-07-09T07:55:08.147 に答える