【发布时间】:2021-07-26 10:33:20
【问题描述】:
Perl DBD::ODBC 从 sql server 插入语句抛出错误
DBD::ODBC does not yet support binding a named parameter more than once
当不打算在此脚本中绑定参数时。我试过自己回答这个问题,并继续这样做,但没有任何运气回答类似的问题。
我有一个脚本可以将 csv(包含日期时间、guid 和 cmets/消息字符串的组合)加载到数据库中。如果需要,我在下面包含了我的脚本的一部分以供进一步分析。在 csv 中超过 350,000 行(大约 20 列)后,它似乎被这个错误挂断了,但我一直无法弄清楚究竟是什么原因造成的。
我试过设置
$self->{dbh}->{odbc_ignore_named_placeholders} = 1;
但没有成功克服这个错误。 csv 中的所有值都用单引号括起来,但其中一些值是包含: 和? 之一/两者的字符串。
在这种情况下,我不打算使用绑定参数或命名占位符 - 只是为了将原始数据输入数据库。
由于故障排除,在这部分脚本中有相当多的打印。整个脚本还没有被有意/无意地优化——我的目标是让它工作。 善良。
这会实例化“连接”对象。由于在这里建立连接,并分配给$self->{dbh},我应该可以将1分配给{odbc_ignore_named_placeholders},但它似乎不起作用。
sub New {
my $class = shift;
my $self = {
dbh => DBI->connect( $dsn ),
dropIfExists => 1, # 1 == drop, 0 == do not drop or create
debug => 1, # 1 == enabled, 0 == disabled
};
$self->{dbh}->{odbc_ignore_named_placeholders} = 1;
bless $self, $class;
return $self;
}
这是在插入语句中准备行的重要部分:
while ( my $row = $csv->getline( $fh ) ) {
my @fields = @{$row};
my @newline = ();
for ( @fields ) {
my $str = $_;
$str =~ s/'+/''/;
my $newString = "'" . $str . "'";
print $newString.NewLine;
push( @newline, $newString );
}
my $line = join( ",", @newline );
$values .= "(" . $line . "),";
$MasterLineCount++;
print FancyLine;
print "MasterLineCount: " . $MasterLineCount . NewLine;
print FancyLine;
$count++;
print FancyLine;
print "Line count: ".$count.NewLine;
print FancyLine;
# sql server allows a maximum of 1000 values (rows) in a
# single insert statement, so this stops the loop, and
# prepares/executes the query. if the loop hits the end of
# the file with a count < 999, it drops out of the
# while loop, and checks if count > 0, if it is, it
# prepares/executes the statement for the remaining
# rows/lines
if ( $count == 999 ) {
$statementCount++;
print FancyLine;
print "Statement Count: " . $statementCount . NewLine;
print FancyLine;
my $insertStmt = "insert into " . $db_name . ".dbo." . $tableName . " (" . $colNames . ") values " . $values;
my $chopTrailingComma = chop( $insertStmt );
# print "Insert Statement: ".NewLine;
# print FancyLine;
# print $insertStmt.NewLine;
# print FancyLine;
# load table
$self->ExecuteStmt( $insertStmt );
#reset values string
$values = "";
#reset count
$count = 0;
}
}
if ( $count > 0 ) {
$statementCount++;
print FancyLine;
print "Statement Count: " . $statementCount . NewLine;
print FancyLine;
my $insertStmt = "insert into " . $db_name . ".dbo." . $tableName . " (" . $colNames . ") values " . $values;
my $chopTrailingComma = chop( $insertStmt );
# load table
$self->ExecuteStmt( $insertStmt );
#reset values string
$values = "";
#reset count
$count = 0;
}
为了清楚起见,这里是ExecuteStmt():
sub ExecuteStmt {
my $self = shift;
my $stmt = shift;
$self->{sth} = $self->{dbh}->prepare( $stmt );
$self->{sth}->execute or die "$stmt".NewLine().FancyLine().$self->{sth}->errstr;
}
【问题讨论】:
-
$self->ExecuteStmt( $insertStmt );是做什么的?$self是什么?请参阅minimal reproducible example 了解更多信息 -
@HåkonHægland 编辑了帖子以包含 ExecuteStmt 子例程,并且 $self 是对当前对象的引用。 Perl Method Functions and Subroutines
标签: sql sql-server perl odbc