【问题标题】:Perl DBI - transfer data between two sql servers - fetchall_arrayrefPerl DBI - 在两个 sql 服务器之间传输数据 - fetchall_arrayref
【发布时间】:2012-08-06 03:29:47
【问题描述】:

我有 2 台服务器:dbh1 和 dbh2,我在其中查询 dbh1 并通过 fetchall_arrayref 方法提取数据。执行查询后,我想将 dbh1 的输出插入到服务器 dbh2 上的临时表中。

我能够同时建立对两台服务器的访问权限,并且能够从两台服务器中提取数据。 1.我从dbh1拉取数据:

while($row = shift(@$rowcache) || shift(@{$rowcache=$sth1->fetchall_arrayref(undef, $max_rows)})) {
        #call to sub insert2tempData
        &insert2tempData(values @{$row});
}

2。然后在 dbh2 上我有一个插入查询:

    INSERT INTO ##population (someid, Type, anotherid)
    VALUES ('123123', 'blah', '634234'); 

问题: 如何将 dbh1 中的 fetchall_arrayref 的批量结果插入服务器 dbh2 上的临时表中(不循环访问各个记录)?

好的 - 所以我能够解决这个问题并能够实现以下代码:

     my $max_rows = 38;
my $rowcache = [];
my $sum   = 0;

if($fldnames eq "ALL"){ $fldnames = join(',', @{ $sth1->{NAME} });}

my $ins = $dbh2->prepare("insert into $database2.dbo.$tblname2 ($fldnames) values $fldvalues");

my $fetch_tuple_sub = sub { shift(@$rowcache) || shift(@{$rowcache=$sth1->fetchall_arrayref(undef, $max_rows)}) };

my @tuple_status;
my $rc;

$rc = $ins->execute_for_fetch($fetch_tuple_sub, \@tuple_status);

my @errors = grep { ref $_ } @tuple_status;

传输有效,但仍然比我通过 SQL Server 导出/导入向导手动传输数据要慢。我注意到的问题是数据逐行流入目的地,我想知道是否可以增加批量传输大小。它下载数据的速度非常快,但是当我结合下载和上传时,速度会急剧下降,在服务器之间传输 5000 行表需要长达 10 分钟。

【问题讨论】:

    标签: sql sql-server perl dbi dbix-class


    【解决方案1】:

    如果你说你的目标是什么(速度?)而不是问一个关于避免循环的具体问题会更好。

    对于 Perl/DBI 方式:

    请查看 DBI 的 execute_arrayexecute_for_fetch,但是由于您没有告诉我们您使用的是哪个 DBD,因此无法说更多。并非所有 DBD 都支持批量插入,当它们不支持时,DBI 会模拟它。 DBD::Oracle 可以,DBD::ODBC 可以(在最近的版本中,请参阅odbc_array_operations),但在后者默认情况下它是关闭的。

    【讨论】:

    • 我正在使用 SQL Server,这是我的连接字符串的一部分:my $dsn = 'DBI:ODBC:Driver={SQL Server}';我正在寻找将结果从 fetchall_arrayref 插入或追加到另一个 SQL 服务器上的表中的速度。
    • 如果您需要从 Perl 执行此操作,那么请务必查看我的答案中的链接,并考虑您是否可以在事务中执行此操作 - 因为这将大大加快速度。
    • 谢谢!我正在查看您的链接,试图了解如何将单个列放大并在单个事务中完成
    • 有没有办法查看我的版本上是否安装了 DBD::ODBC?你有我可以利用的 odbc 批量插入操作的示例吗?
    • perl -MDBD::ODBC -le '打印 $DBD::ODBC::VERSION'。在execute_array测试中execute_for_fetch/execute_array的未解压的DBD::ODBC的t子目录中有例子。
    【解决方案2】:

    您没有提及您使用的是哪个版本的 SQL Server。首先,我会研究该版本的“BULK INSERT”支持。

    您也没有提到涉及多少行。我会假设它们适合内存,否则批量插入将不起作用。

    您可以将fetchall_arrayref 的输出转换为“BULK INSERT”操作所需的语法。

    【讨论】:

    • 感谢您的帮助!以下是规格:SQL Server 2008 和我希望通过 3 列传输大约 10,000 个(行数可能会波动)
    • 您在查找 BULK INSERT 支持时发现了什么?您是否尝试过将要返回的行转换为该格式的 SQL 语句?
    • 我目前正在尝试转换为数组来保存整个列,然后我会尝试测试批量插入...感谢您的帮助!我很惊讶为什么没有人尝试在 perl 中编写 2 个服务器之间的数据传输...
    • 谢谢,这真的很有帮助,我正在寻找:
    猜你喜欢
    • 1970-01-01
    • 2018-02-11
    • 1970-01-01
    • 2014-04-12
    • 2022-01-05
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多