所以我几乎是编码方面的新手,而且我通过试验和错误来学习,这次我尝试使用Perl的数据库,实际上当我只使用3个表头时它很有效(终端, Zeitstempel,Ergebnisnummer)但是当我尝试添加更多标题(Ergebnistext,Transart,Belegnummer,Trace,Betrag,Kartenart,Kartennummer,Entrymode)时,它总是给我一个语法错误,我检查了半个小时但是找不到错误。如果有人知道为什么我会感激你的帮助!这部分代码看起来像这样:
foreach $file (@file)
{
$currentfile = "$currentdir\\$file";
open(zloop, "<", $currentfile) or die "Failed to open file: $!\n";
while ( <zloop> ) {
my %row;
chomp;
@row{@headers} = split /;/;
my $tid = $row{'tid'};
my $zeit = $row{'zeit'};
my $ergebnisnummer = $row{'ergebnisnummer'};
my $ergebnistext = $row{'ergebnistext'};
my $transart = $row{'transart'};
my $belegnummer = $row{'belegnummer'};
my $trace = $row{'trace'};
my $betrag = $row{'betrag'};
my $kartenart = $row{'kartenart'};
my $kartennummer = $row{'kartennummer'};
my $entrymode = $row{'entrymode'};
my $sth = $dbh->prepare("INSERT INTO `teso`( Terminal, Zeitstempel, Ergebnisnummer, Ergebnistext, Transart, Belegnummer, Trace, Betrag, Kartenart, Kartennummer, Entrymode )
values ( $tid, $zeit, $ergebnisnummer, $ergebnistext, $transart, $belegnummer, $trace, $betrag, $kartenart, $kartennummer, $entrymode )");
$sth->execute() or die $DBI::errstr;
$sth->finish();
我没有将变量名称更改为英语,因为它们可能导致语法错误。这是错误消息:
DBD :: mysql :: st执行失败:您的SQL语法出错; 检查与您的MySQL服务器版本对应的文件 在第2行的'')'附近使用正确的语法 C:\ Users \ Desktop \ findlogstamp \ sqlneu.pl lin e 50,第1行。你 您的SQL语法有错误;检查对应的手册 您的MySQL服务器版本,以便在'')'附近使用正确的语法 第2行在C:\用户s \ Desktop \ findlogstamp \ sqlneu.pl第50行, 第1行。
答案 0 :(得分:6)
您可能会因为以字符串形式传递变量而导致引用错误。您应该使用占位符。
尝试做这样的事情:
{{1}}
我还包括mwp's answer too。
同样值得一读Borodins Answer,以便更全面地了解perl中的占位符和SQL。
答案 1 :(得分:3)
我相信&#34;追踪&#34;是MySQL中的保留字。尝试在列名称周围添加反引号。
答案 2 :(得分:1)
必须正确引用SQL表达式中的值。简单的数值不需要引用,我想你使用的前三列 - 终端ID,时间戳和结果号 - 都是数字,这就是它们没有引号的原因
DBI
模块提供函数数据库句柄方法quote
,它将为您执行此操作(以及quote_identifier
对标识符执行相同操作,例如表和列名称) 。但是prepare
使用占位符的SQL语句总是更安全,而不是尝试自己将值插入到字符串中。然后,可以在execute
调用中提供实际值,wehen DBI
会在将所有值插入语句之前隐式调用$dbh->quote
最好prepare
语句一次,因为句柄可能会被重复使用。并且无需从%row
哈希中提取一系列标量变量 - 可以使用哈希切片直接从哈希中获取正确的字段到{{1}打电话。但是,最好在数组中保留字段名称列表,就像使用execute
一样;实际上,您的@headers
可能与我的@headers
相同,在这种情况下,无需同时定义<{p>}
我在 here document 中使用了SQL字符串。如果你想做同样的事情,那么要小心在结束标记@items
之前或之后必须有没有空格,否则它将无法找到
请注意,我已将END_SQL
与列表重复运算符join
一起使用,以在QSL中生成正确数量的问号占位符。以这种方式执行操作更加安全,以避免错误计数,并允许在不更改SQL语句的情况下更改字段数。如果您愿意,可以x
查看已构建的SQL
我希望这会有所帮助
print "$sql\n"
答案 3 :(得分:0)
我认为,错误是因为
无论如何,将值插入查询字符串是一个非常糟糕的主意。
您可以使用单引号替换查询周围的引号(以消除不需要的插值)并替换要使用占位符插入的值。然后你应该将实际值传递给execute()方法。像这样:teso
周围的反引号是由perl插值的。
my $sth = $dbh->prepare('INSERT INTO teso( Terminal, Zeitstempel, Ergebnisnummer, Ergebnistext, Transart, Belegnummer, Trace, Betrag, Kartenart, Kartennummer, Entrymode )
values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )');
$sth->execute($tid, $zeit, $ergebnisnummer, $ergebnistext, $transart, $belegnummer, $trace, $betrag, $kartenart, $kartennummer, $entrymode) or die $DBI::errstr;
$sth->finish();
或者,如果您只想插入一行,可以用一个do()替换所有这些:
$dbh->do('INSERT INTO teso( Terminal, Zeitstempel, Ergebnisnummer, Ergebnistext, Transart, Belegnummer, Trace, Betrag, Kartenart, Kartennummer, Entrymode ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )', undef,
$tid, $zeit, $ergebnisnummer, $ergebnistext, $transart, $belegnummer, $trace, $betrag, $kartenart, $kartennummer, $entrymode ) or die $DBI::errstr;