[英]Why is MySQL giving me a syntax error?
所以我在编码方面是个新手,我有点试错了,这次我尝试使用Perl使用DB,实际上当我只使用3个表头(Terminal,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语法有错误; 在C:\\ Users \\ Desktop \\ findlogstamp \\ sqlneu.pl lin e 50,第1行的第2行中,检查与您的MySQL服务器版本相对应的手册,以在'')'附近使用正确的语法。您的SQL语法; 在第2行的C:\\ User s \\ Desktop \\ findlogstamp \\ sqlneu.pl第50行第1行中,检查与MySQL服务器版本相对应的手册,以在``)'附近使用正确的语法。
由于将变量作为字符串传递,可能会引起引用错误。 您应该改为使用占位符。
尝试做这样的事情:
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;
我也包括了mwp的答案 。
还值得花时间阅读《 Borodins答案》 ,以获得在Perl中处理占位符和SQL的更彻底的方法。
我相信“ trace”是MySQL中的保留字。 尝试在列名称周围添加反引号。
SQL表达式中的值必须正确引用。 简单的数字不需要用引号引起,并且我想象您使用的前三列-终端ID,时间戳和结果号-都是数字,这就是为什么它们不用引号就可以工作的原因
DBI
模块提供函数数据库句柄方法quote
(将为您完成此操作)(以及quote_identifier
对标识符(例如表名和列名)执行相同的操作)。 但是,使用占位符 prepare
SQL语句总是比尝试自己将值插值到字符串中要安全得多。 然后,可以在execute
调用中提供实际值,因为DBI
会将所有值隐式调用$dbh->quote
,然后再将它们插入到语句中
这也是最好prepare
一份声明中只有一次 ,当手柄然后可以重复使用。 无需从%row
哈希中提取一系列标量变量- 哈希切片可用于直接从哈希中获取正确的字段,并execute
调用。 但是,最好像使用@headers
一样在数组中保留字段名称的列表。 实际上,您的@headers
可能与我的@items
相同,在这种情况下,无需定义两者
我已将此处文档用于SQL字符串。 如果要执行相同的操作,请注意结束标记END_SQL
之前或之后必须没有空格 ,否则将找不到该END_SQL
请注意,我已经使用join
与列表重复运算符x
一起在QSL中产生了正确数量的问号占位符。 用这种方式做事要安全得多,这样可以避免错误计数,并允许在不更改SQL语句的情况下更改字段数。 您可以print "$sql\\n"
以查看已构建的SQL
我希望这有帮助
my @items = qw/
tid zeit ergebnisnummer ergebnistext transart
belegnummer trace betrag kartenart kartennummer entrymode
/;
my $sql = sprintf <<END_SQL, join ', ', ('?') x @items;
INSERT INTO teso (
Terminal, Zeitstempel, Ergebnisnummer, Ergebnistext, Transart,
Belegnummer, Trace, Betrag, Kartenart, Kartennummer, Entrymode
)
VALUES (%s)
END_SQL
my $insert = $dbh->prepare($sql);
for my $file ( @file ) {
my $current_file = "$currentdir\\$file";
open my $fh, '<', $current_file or die qq{Unable to open "$current_file" for input: $!};
while ( <$fh> ) {
my %row;
@row{@headers} = split /;/;
$insert->execute(@row{@items}) or die $sth->errstr;
}
}
我认为,错误是因为
无论如何,将值插值到查询字符串中是一个非常糟糕的主意。 您可以用单引号替换查询周围的引号(以消除不希望的插值),并用占位符替换要插入的值。 然后,您应该将实际值传递给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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.