通过已经工作的连接字符串在远程 SQL 服务器中插入本地 .csv 数据

Insert local .csv data in remote SQL Server via already working connection string

我正在使用 ODBC 和 FreeTDS 从 linux 服务器连接到 MS SQL Server 2008(连接字符串)。我需要在 SQL 服务器上的 table 中的 RHEL 服务器上获取本地 .CSV 文件的内容。然而,至少可以说我的 SQL 有点破旧。我该如何进行?我对DBI也是陌生的

#!/usr/bin/perl

# PERL MODULES WE WILL BE USING
use DBI;
use DBD::ODBC;

my $data_source = q/dbi:ODBC:MSSQLServer/; # DSN string from /etc/odbc.ini
my $user = q/Username/;
my $password = q/Password/;
my $dbh = DBI->connect($data_source, $user, $password, {RaiseError => 0, PrintError => 1}) or die "Can't connect to $data_source: $DBI::errstr";

.csv 文件包含 2 个值,每行用逗号分隔。每一行都必须插入 table。数据库中的 table 有 2 列(attribute1attribute2)。

.csv 内容示例:

server1, id1

server2, id2

server3, id1

server4, id9

主键是已经设置的数字值,所以我认为重复值不是问题。

此时在您的代码中您只连接到您的数据库。请查看 Whosebug 中的示例,它可以帮助您了解下一步的操作(它指的是 MySQL,但它仍然具有指导意义):

Perl inserting into MySQL DB

此外,我会推荐用户 Matt Jacob 在他的评论中提到的内容以及 Tim Bunce 和 Alligator Descartes 的书 "Programming the Perl DBI: Database programming with Perl"。

HTH

您的 test.csv 包含:

server1, id1

server2, id2

server3, id1

server4,id9

================================

使用下面的代码进行批量插入。

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

open(my $file, '<' , "test.csv");
my @all_data;
while(my $data = <$file>){
    chomp($data);
    if($data){
        $data =~ s/^\s+//;
        $data =~ s/\s+$//;
        my $string = qq{($data)};
        push(@all_data,$string)
    }
}
close $file;
my $sql_string = join(',',@all_data);

my $dbname   = "DBName";
my $dsn      = "dbi:SQLite:dbname=$dbname";
my $username = "user";
my $password = "pass";
my $dbh = DBI->connect($dsn, $username , $password, {
   PrintError       => 0,
   RaiseError       => 1,
   AutoCommit       => 1,
   FetchHashKeyName => 'NAME_lc',
});
my $sql = qq{INSERT INTO ServerDetails (server, id) VALUES $sql_string};
$dbh->do($sql);
$dbh->disconnect;

使用下面的代码进行单次插入:

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

my $dbname   = "DBName";
my $dsn      = "dbi:SQLite:dbname=$dbname";
my $username = "user";
my $password = "pass";
my $dbh = DBI->connect($dsn, $username, $password, {
   PrintError       => 0,
   RaiseError       => 1,
   AutoCommit       => 1,
   FetchHashKeyName => 'NAME_lc',
});
open(my $file, '<' , "test.csv");
while(my $data = <$file>){
    chomp($data);
    if($data){
        $data =~ s/^\s+//;
        $data =~ s/\s+$//;
        my $sql = qq{INSERT INTO ServerDetails (server, id) VALUES ($data)};
        $dbh->do($sql);
    }
}
close $file;
$dbh->disconnect;

抱歉,我没有意识到我问的有点多了。我实际上是自己想出来的。所以我想我把代码留在这里以防万一有人需要它。祝你有美好的一天!

#!/usr/bin/perl

# PERL MODULES
use strict;
use DBI;
use DBD::ODBC;
use Text::CSV;
use List::MoreUtils qw(each_array);

# SOME VARIABLES
my $file = '/tmp/Stevo/clientlist.csv';
my $csv = ();
my $fh = ();
my $data_source = q/dbi:ODBC:MSSQLServer/;
my $user = q/username/;
my $password = q/password/;

# WRITE HOSTNAMES FROM CSV TO ARRAY
my @hostnames;
open (my $csv, '<', $file) || die "cant open";
foreach (<$csv>) {
   chomp;
   my @fields = split(/\,/);
   push @hostnames, $fields[0];
}
# WRITE CLIENTVERSIONS FROM CVS ARRAY
my @clientversions;
open (my $csv, '<', $file) || die "cant open";
foreach (<$csv>) {
   chomp;
   my @fields = split(/\,/);
   push @clientversions, $fields[1];
}
# CONNECTION STRING
my $dbh = DBI->connect($data_source, $user, $password, {RaiseError => 0, PrintError => 1}) or die "Can't connect to $data_source: $DBI::errstr";

# INSERTION CODE
my $sth_insert = $dbh->prepare('INSERT INTO dbo.LegatoClients (ClientName, ClientVersion) VALUES (?, ?)')
  or die $dbh->errstr;
   # EVERYTIME $EA IS CALLED THE NEXT LINE OF THE ARRAYS WILL BE RETURNED 
my $ea = each_array(@hostnames, @clientversions);
   # SET VALUES USING THE EVERYTIME ARRAY
while ( my ($val_hostnames, $val_clientversions) = $ea->() ) {
  $sth_insert->execute($val_hostnames, $val_clientversions) or die $dbh->errstr;
}