【问题标题】:How to catch SQL::Parser errors in Perl如何在 Perl 中捕获 SQL::Parser 错误
【发布时间】:2013-05-14 13:58:13
【问题描述】:

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

【问题讨论】:

    标签: perl


    【解决方案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()得到“假”返回值,但不知道错误是什么。

    parse()POD if you check it 对此进行了介绍:

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

    • 如果 PrintError 为真,则 SQL 语法错误将被发送为 对 STDERR 的警告(即,如果是 STDERR,则向屏幕或文件发出警告 已重定向)。默认情况下设置为 true 意味着除非你特地关闭它,否则所有错误 会被举报。

    • 如果 RaiseError 为真,则 SQL 语法错误将导致 脚本死,(即脚本将终止,除非被包装 在评估中)。默认情况下设置为 false,这意味着 除非您专门打开它,否则脚本将 即使有 SQL 语法错误也能继续操作。

    【讨论】:

    • 附带说明,这听起来是一种非常狡猾的 SQL 解析方式。如果 SQL 中的字符串文字中存在逗号或“=”怎么办?
    • DVK - 问题不在于我的 SQL 是否适合解析,问题是如果解析了任何不正确的 SQL,我如何捕获此类 SQL 并打印错误消息。
    • 顺便说一下,问题仅出自 TO_DATE 函数。当我解析以下 SQL 时,它通过了:codeuPdate scott.emp set ename='SCT%',emp_date='04/16/2011', empno='15645' WHERE dept=20 and ename IN(select ename from emp where empno='1111');code
    猜你喜欢
    • 2020-03-31
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    相关资源
    最近更新 更多