我试图将一些数据从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;
Run Code Online (Sandbox Code Playgroud)
这里有一些问题.我将列出那些首先会给你错误信息的.
<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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我决定事先准备好声明并重新使用它.这样可以在循环中节省大量时间,因为DB会记住该语句.
从列表上下文中的文件句柄(即<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;
Run Code Online (Sandbox Code Playgroud)