【问题标题】:IN in WHERE-clause is not being parsed correctly using SQL::Statement没有使用 SQL::Statement 正确解析 WHERE 子句中的 IN
【发布时间】:2020-05-12 03:14:17
【问题描述】:

我正在使用此处提供的示例的略微修改版本:https://metacpan.org/pod/distribution/SQL-Statement/lib/SQL/Statement/Structure.pod

use SQL::Statement;
use Data::Dumper;

my $sql = q{
SELECT c1
     , col2 as c2
     , c3
FROM table1 t1, table2 t2
WHERE t1.c1 = t2.c2
 and  t1.c1 in (11111, 22222, 33333)
GROUP by t1.c1
};

my $parser = SQL::Parser->new('ANSI');
$parser->{RaiseError}=1;
$parser->{PrintError}=0;
my $stmt = SQL::Statement->new($sql, $parser);
print Dumper($stmt->where_hash());

但是当我这样做时,我得到了这个没有意义的错误,因为它是一个非常常见的结构:

Bad table or column name: '11111,22222,33333' has chars not alphanumeric or underscore! at /home/palert/perl5/perlbrew/perls/perl-5.28.1/lib/site_perl/5.28.1/SQL/Statement.pm line 90.

我错过了什么?

【问题讨论】:

  • 似乎是解析器的错误/限制。尝试联系作者?
  • 我认为 SQL 不应该是 and t1.c1 in (11111, 22222, 33333) 而是 and t1.c1 in ('11111', '22222', '33333') -- 请注意,引用可以是不同的类型,请查阅您的数据库文档。
  • 我发现SQL::Statement 真的很挑剔,并且没有处理文档似乎建议的很多事情。
  • 小鲍比桌响起打招呼。
  • 嗨@Ether,我不得不查一下,但是这很有趣。我上面的例子不是来自一些实际代码,而是一个简化版本,旨在说明问题。

标签: sql perl dbi dbd sql-parser


【解决方案1】:

私下给维护者发邮件而不是检查未解决的问题或阅读https://metacpan.org/pod/SQL::Statement#Where-can-I-go-for-help?仔细并没有显示您在自己解决问题上投​​入了多少时间。

Polar Bear 从 SQL::Statement 的角度给了你正确的答案。 我知道它有一些怪癖,但它是一个已有 20 年历史的 Perl5 模块,因此它没有使用新的花哨抽象,例如通过 Moose 或 wtf 进行的类型系统。

OTOH - 您可以按照 Ether 的建议使用占位符。比你在执行时传递值,而不是在解析期间传递值。

【讨论】:

    【解决方案2】:

    底线是 SQL::Statement 相当有限,只能处理基本的 SQL。缺乏对“in (numeric list)”的支持只是其中之一。不能处理子查询对我来说是另一个大问题。

    对于我正在从事的项目,我对 SQL::Statement 寄予厚望,我想将 Sybase SQL 即时转换为 MySQL SQL 语句。但它不会起作用。

    我决定创建一个围绕 https://github.com/dmtolpeko/sqlines 的 Perl 包装器。这并不完美,但它让我更接近我的目标。

    这不是一个完整的 Perl 解决方案,但到目前为止它似乎可以工作并且速度非常快。

    感谢大家的 cmets/answers。

    【讨论】:

      猜你喜欢
      • 2014-06-25
      • 2016-12-17
      • 2023-03-26
      • 2013-10-16
      • 2023-03-06
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      相关资源
      最近更新 更多