Perl/DBI/FreeTDS/SQLAzure 一些插入被忽略

Posted

技术标签:

【中文标题】Perl/DBI/FreeTDS/SQLAzure 一些插入被忽略【英文标题】:Perl/DBI/FreeTDS/SQLAzure Some inserts ignored 【发布时间】:2012-11-06 06:49:36 【问题描述】:

我在使用 DBI 和 FreeTDS(在 Ubuntu 上)将一些数据插入 SQL Azure 时遇到了一个间歇性问题。可能会出现问题并忽略某些行,然后我可以再次运行它而不会出现问题。

脚本:

print "Importing File $file: to Staging Table\n";
    open my $info, $file or die "Could not open $file: $!";

$dbh->do("EXEC DWTOOLS.InitStage;") or die $DBI::errstr ; #truncates the table

    my $sth = $dbh->prepare("INSERT INTO DWSTAGE.CDRImport (LINE) VALUES(?);") or die $DBI::errstr ;
    my $counter = 0;
    while( my $line = <$info>)  
            $line =~ s/\r?\n$//;
            $counter++;
    print "Loading line $counter: $line\n" ;
            my $rc = $sth->execute($line) or die $DBI::errstr ;
            print "Result: $rc\n";
    
    close $info;


print "\nChecking Data Warehouse: $counter lines expected\n" ;
my $checksth = $dbh->prepare("EXEC DWTOOLS.CheckStage ?;") or die $DBI::errstr ;
    my $checkrc = $checksth->execute($counter) or die $DBI::errstr ;

my @row;
while ( @row = $checksth->fetchrow_array(  ) ) 
    print "Row: @row\n";

给出输出:

Importing File filename: to Staging Table
Loading line 1: data redacted
Result: 1
Loading line 2: data redacted
Result: 1
etc. etc. with no indication of errors
Loading line 165: data redacted
Result: 1
Loading line 166: data redacted
Result: 1

Checking Data Warehouse: 166 lines expected
Row: 35 166
Row: 35 166
Loading to Data Warehouse

所以当我查看表格时,它显示所有开始行在它开始工作时一直丢失到某个点 - 可靠 - 直到结束 - 所以基本上,文件的最后 35 行被加载并且它们从 1 开始到 35,其中第 1 行实际上是第 (166-35+1) 行或其他。 Azure 中的表有一个 PK 集群 IDENTITY 列,它从 1 开始并且没有间隙,所以就像第一个这么多插入已被删除而没有任何错误指示。这发生在各种文件、各种大小和文件中的各个位置。

文件在循环中处理,每个文件都被打开、处理和关闭,以防与这种奇怪的行为有任何关系。该语句为每个文件重新准备一次,但如果这可能导致问题,SQL Azure 连接将在程序的整个生命周期内保持。如果连接失败,我仍然希望程序死掉,但从执行返回的错误代码的缺乏来看,我不确定我会得到任何错误指示。

如果我继续重新运行程序,所有的行都进来了,一切都很好。

我不确定要得出什么结论。目前,我的结论是 FreeTDS 存在缺陷且不可靠。

【问题讨论】:

你需要 $dbh->commit() 某处吗? 【参考方案1】:

看起来数据库在截断过程完成之前执行插入。如果这是一个存储过程,您可以添加某种标志它已完成并在继续之前检查它。或者最好还是将整个数据库调用集合到一个事务中。

【讨论】:

好吧,已经很久了,我放弃了尝试从 Linux 访问这个数据库的尝试。我想如果连接以某种方式允许多个同时操作并在第一个存储过程完成之前返回,这是可能的。它在 Windows 上没有这个问题。

以上是关于Perl/DBI/FreeTDS/SQLAzure 一些插入被忽略的主要内容,如果未能解决你的问题,请参考以下文章