我尝试将一些数据从CSV上传到MySQL数据库 - 但它无法正常工作
下面是我的代码
#!/usr/bin/perl -w
use DBI;
use strict;
use TEXT::CSV;
use warnings;
my $driver = "mysql";
my $database = "test";
my $host = "localhost"
my $databaseport = "3306";
my $userid = "root";
my $password = "password";
my $csv = "C:/Perl/scripts/table.csv";
my $dsn = "dbi:mysql:dbname=$databasename;host=$dbhost;port=$dbport;";
open (CSV, "$csv") or die "Couldn't open csvfile: $!";
my $dbh = DBI->connect($dsn, $userid, $password,{ RaiseError => 1})
or die "Could not connect to database! $DBI::errstr";
{
local $/ = undef;
$dbh->do("INSERT INTO student (stud_id,stud_name,dept_id,stud_mark,stud_address)
values (?, ?, ?, ?, ?)", undef, <CSV>);
}
$dbh->disconnect;
close CSV;
答案 0 :(得分:6)
这里有一些问题。我将列出那些首先会给你错误信息的内容。
<CSV>
传递了csv文件的第一行。这将给出错误信息。然后你的逻辑有问题。您正在将完整文件传递给DB(作为第一个参数)。那没有意义。您需要split
输入或使用Text :: CSV来执行此操作并逐行读取文件。
此外,现在最好将open
与三个参数一起使用,并使文件句柄有词汇。
我已经将所有这些都写成了自制CSV处理的例子。如果您的文件更复杂,请阅读Text :: CSV并使用它。
use DBI;
use strict;
use warnings;
my $csv = "C:/Perl/scripts/table.csv";
# omitted settings here ...
my $dbh = DBI->connect($dsn, $userid, $password,{ RaiseError => 1})
or die "Could not connect to database! $DBI::errstr";
open (my $fh, '<', $csv)
or die "Couldn't open csvfile: $!";
# prepare statement handle for reuse in the loop
my $sth = $dbh->prepare(qq{
INSERT INTO student(stud_id,stud_name,dept_id,stud_mark,stud_address)
VALUES (?, ?, ?, ?, ?)});
# read the file line by line
while (my $line = <$fh>) {
chomp $line; # remove newline
$sth->execute( split /;/, $line ); # assuming the separator is a semicolon
}
close $fh;
# DB handle will disconnect implicitly on end of program
如您所见,我决定prepare the statement预先重新使用它。这样可以在循环中节省大量时间,因为DB会记住该语句。
答案 1 :(得分:6)
从列表上下文中的文件句柄(即代码中的<CSV>
位)读取文件中的所有行并将其作为列表返回。因此,您的?, ?, ?, ?
占位符每个都会从文件中获得整行(包括末尾的换行符)。对于某些字段(可能是dept_id
?),这可能不是有效值,因此INSERT
语句失败。
虽然实际上,你也将$/
设置为undef,这使得它甚至成为了wrongerer。 $/
在读取文本文件时更改了Perl的新行概念。将其设置为undef意味着Perl会将整个文件视为一行。
猜测一下,您要做的是一次读取一行CSV文件,并将每个文件泵入数据库。
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Text::CSV; # case-sensitive!
my $driver = "mysql";
my $database = "test";
my $host = "localhost"
my $databaseport = "3306";
my $userid = "root";
my $password = "password";
my $csv = "C:/Perl/scripts/table.csv";
# Connect to database.
my $dsn = "dbi:mysql:dbname=$databasename;host=$dbhost;port=$dbport;";
my $dbh = DBI->connect($dsn, $userid, $password,{ RaiseError => 1})
or die "Could not connect to database! $DBI::errstr";
# DBI can be more efficient if you prepare the SQL query once, and then
# execute it multiple times, rather than calling `do` for each insert.
my $sth = $dbh->prepare(<<'SQL');
INSERT INTO student (stud_id,stud_name,dept_id,stud_mark,stud_address)
VALUES (NULL, ?, ?, ?, ?)"
SQL
# Open the CSV file.A
open my $CSV, '<', $csv
or die "Couldn't open csvfile: $!";
# Create an instance of Text::CSV.
my $reader = Text::CSV->new;
# Use Text::CSV to read a line.
while (my $row = $reader->getline($CSV))
{
# Insert into database.
$sth->execute( @$row );
}
# Clean up (optional; Perl will do this when your script ends anyway).
$dbh->disconnect;
close $CSV;