0

我有一个更新语句,我正在用 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 行抛出错误。

4

1 回答 1

1

我不认为“TO_DATE”函数是你错误的根源。

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%'

ETC...


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

    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标志,它会警告你。您可以通过捕获警告信号来捕获警告,如此处所示SOPerlMaven

  • 如果你没有设置任何一个,你会得到“假”的返回值,parse()但不知道错误是什么。

如果您检查它,这将包含在parse()'s POD中:

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

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

  • 如果 RaiseError 为真,则 SQL 语法错误将导致脚本终止,(即除非包含在 eval 中,否则脚本将终止)。这默认设置为 false,这意味着除非您专门打开它,否则即使出现 SQL 语法错误,脚本也会继续运行。

于 2013-05-14T14:08:57.940 回答