如何在Perl中捕获SQL :: Parser错误

时间:2013-05-14 13:58:13

标签: perl

我有一个更新语句,我用SQL :: Parser

解析
uPdate scott.emp 
set ename='SCT%',emp_date=TO_DATE('04/16/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'),empno='15645' 
WHERE dept=20 and ename IN(select ename from emp where empno='1111');

但由于TO_DATE函数无法使用SQL :: Parser进行解析,因此会抛出错误:

Incomplete SET clause! at ./post_audit.pl line 173
Incomplete SET clause! at ./post_audit.pl line 173

我如何捕获此类错误? eval可以做到吗?没找到相同的文档。

解析SQL语句的代码:

   +12  use SQL::Parser;

   +34  my $statement = "uPdate scott.emp set ename='SCT%',emp_date=TO_DATE('04/16/2011 00:00:00', 'MM/DD/YYYY HH24:MI:SS'),empno='15645' WHERE dept=20 and ename IN(select ename from emp where empno='1111')";

  +172      my $parser = SQL::Parser->new('AnyData', {RaiseError=>1} );
  +173      $parser->parse($statement);

解析语句时在第173行抛出错误。

1 个答案:

答案 0 :(得分:1)

我认为“TO_DATE”功能不是您错误的来源。

source code到SQL :: Parser模块说:

my @sets = split /,/,$set_string;
my(@cols,@vals);
for(@sets) {
    my($col,$val) = split / = /,$_;
    return $self->do_err('Incomplete SET clause!') if !$col or !$val;

注意“=”在正则表达式中用空格包围:“/ = /

因此,你应该用空间包围你的等号:

set ename='SCT%'

应该是

set ename = 'SCT%'

等...


就处理它而言,它取决于您在构造函数中设置的错误标志:

    sub do_err {
        ...
        warn $err if $self->{"PrintError"};
        die if $self->{"RaiseError"};
        return undef;
    }
  • 如果设置RaiseError标志,则代码将会死亡。

    my $parser = SQL::Parser->new('AnyData', {RaiseError=>1} );
    

    因此,您需要在eval {}调用周围包裹$parser->parse(),并检查$@值是否有错误字符串。

  • 如果您设置了PrintError标志,它会发出警告。您可以通过捕获警告信号来捕获警告,如here on SOon PerlMaven所示。

  • 如果您未设置任何一个,则会从parse()获得“false”返回值,但不知道错误是什么。

parse()的{​​{3}}:

涵盖了这一点
  

除了用a检查parse()的返回值   像$ success一样的变量,你可以使用PrintError和   像在DBI脚本中一样使用RaiseError属性:

     
      
  • 如果PrintError为true,则将发送SQL语法错误   警告STDERR(即屏幕或文件,如果STDERR   已被重定向)。默认设置为true   意味着除非您专门将其关闭,否则所有错误   将被报道。

  •   
  • 如果RaiseError为true,那么SQL语法错误将导致   脚本死掉(即脚本将终止,除非包装   在评估中)。默认情况下,此值设置为false   除非你专门打开它,否则脚本会   即使存在SQL语法错误,也会继续运行。

  •