【问题标题】:Insert local .csv data in remote SQL Server via already working connection string通过已经工作的连接字符串在远程 SQL Server 中插入本地 .csv 数据
【发布时间】:2016-03-08 08:16:13
【问题描述】:

我正在使用 ODBC 和 FreeTDS 从 linux 服务器连接到 MS SQL Server 2008(连接字符串)。我需要在 SQL 服务器上的表中获取 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 个值,每行用逗号分隔。必须在表中插入每一行。数据库上的表有 2 列(attribute1attribute2)。

.csv 内容示例:

服务器1,id1

服务器2,id2

server3,id1

server4,id9

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

【问题讨论】:

  • 所以您希望我们为您解析 CSV 文件,遍历其内容,并将每一行作为新记录插入数据库中?
  • 事情是这样的——看起来你自己并没有付出体面的努力来解决这个问题。您发布了 10 行代码,其中只有 1 行真正起作用。我不会为你做你的工作,但是我会为你指出正确的方向。完整阅读所有这些内容:DBIText::CSV/split()INSERT (Transact-SQL)。然后回来编辑您的问题,我们会看看我们能做些什么。

标签: sql perl sql-server-2008 odbc dbi


【解决方案1】:

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

Perl inserting into MySQL DB

另外,我会推荐用户 Matt Jacob 在他的 cmets 中提到的内容,以及 Tim Bunce 和 Alligator Descartes 所著的“Perl DBI 编程:使用 Perl 进行数据库编程”一书。

HTH

【讨论】:

    【解决方案2】:

    您的 test.csv 包含:

    服务器1,id1

    服务器2,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;
    

    【讨论】:

      【解决方案3】:

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

      #!/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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-24
        • 1970-01-01
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多