关于 DBD::CSB 语句函数的问题

发布于 2024-09-04 12:21:05 字数 1823 浏览 6 评论 0原文

来自 SQL::Statement::Functions 文档:

函数语法

直接使用 SQL::Statement/SQL::Parser 解析 SQL 时,函数(内置函数或用户定义函数)可能出现在 SQL 语句中可能出现值、列名、表名或谓词的任何位置。当通过 DBD 或在解析和执行 SQL 的任何其他上下文中使用模块时,函数可以出现在相同位置,但不能出现在包含 FROM 子句的 SELECT 语句的列选择子句中。

# 对解析和执行都有效

 SELECT MyFunc(args);
 SELECT * FROM MyFunc(args);
 SELECT * FROM x WHERE MyFuncs(args);
 SELECT * FROM x WHERE y < MyFuncs(args);

# 仅对解析有效(不适用于 DBD)

 SELECT MyFunc(args) FROM x WHERE y;

读到此内容,我预计示例中的第一个 SELECT 语句不应该起作用,而第二个应该起作用,但事实恰恰相反。

#!/usr/bin/env perl
use warnings; use strict;
use 5.010;
use DBI;

open my $fh, '>', 'test.csv' or die $!;
say $fh "id,name";
say $fh "1,Brown";
say $fh "2,Smith";
say $fh "7,Smith";
say $fh "8,Green";
close $fh;

my $dbh = DBI->connect ( 'dbi:CSV:', undef, undef, {
    RaiseError => 1,
    f_ext      => '.csv',
    });

my $table = 'test';

say "\nSELECT 1";
my $sth = $dbh->prepare ( "SELECT MAX( id ) FROM $table WHERE name LIKE 'Smith'" );
$sth->execute ();
$sth->dump_results();

say "\nSELECT 2";
$sth = $dbh->prepare ( "SELECT * FROM $table WHERE id = MAX( id )" );
$sth->execute ();
$sth->dump_results();

输出:

选择 1
“7”
1 行

选择2
/usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm 第 2893 行存在未知函数“MAX”。
DBD::CSV::db 准备失败:未知函数“MAX”位于 /usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm 第 2894 行。
[for 语句“SELECT * FROM test WHERE id = MAX( id )”]位于 ./so_3.pl 第 30 行。
DBD::CSV::db 准备失败:未知函数“MAX”位于 /usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm 第 2894 行。
[for 语句“SELECT * FROM test WHERE id = MAX( id )”]位于 ./so_3.pl 第 30 行。

有人可以解释我这种行为吗?

From the SQL::Statement::Functions documentation:

Function syntax

When using SQL::Statement/SQL::Parser directly to parse SQL, functions (either built-in or user-defined) may occur anywhere in a SQL statement that values, column names, table names, or predicates may occur. When using the modules through a DBD or in any other context in which the SQL is both parsed and executed, functions can occur in the same places except that they can not occur in the column selection clause of a SELECT statement that contains a FROM clause.

# valid for both parsing and executing

 SELECT MyFunc(args);
 SELECT * FROM MyFunc(args);
 SELECT * FROM x WHERE MyFuncs(args);
 SELECT * FROM x WHERE y < MyFuncs(args);

# valid only for parsing (won't work from a DBD)

 SELECT MyFunc(args) FROM x WHERE y;

Reading this I would expect that the first SELECT-statement of my example shouldn't work and the second should but it is quite the contrary.

#!/usr/bin/env perl
use warnings; use strict;
use 5.010;
use DBI;

open my $fh, '>', 'test.csv' or die $!;
say $fh "id,name";
say $fh "1,Brown";
say $fh "2,Smith";
say $fh "7,Smith";
say $fh "8,Green";
close $fh;

my $dbh = DBI->connect ( 'dbi:CSV:', undef, undef, {
    RaiseError => 1,
    f_ext      => '.csv',
    });

my $table = 'test';

say "\nSELECT 1";
my $sth = $dbh->prepare ( "SELECT MAX( id ) FROM $table WHERE name LIKE 'Smith'" );
$sth->execute ();
$sth->dump_results();

say "\nSELECT 2";
$sth = $dbh->prepare ( "SELECT * FROM $table WHERE id = MAX( id )" );
$sth->execute ();
$sth->dump_results();

outputs:

SELECT 1
'7'
1 rows

SELECT 2
Unknown function 'MAX' at /usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm line 2893.
DBD::CSV::db prepare failed: Unknown function 'MAX' at /usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm line 2894.
[for Statement "SELECT * FROM test WHERE id = MAX( id )"] at ./so_3.pl line 30.
DBD::CSV::db prepare failed: Unknown function 'MAX' at /usr/lib/perl5/site_perl/5.10.0/SQL/Parser.pm line 2894.
[for Statement "SELECT * FROM test WHERE id = MAX( id )"] at ./so_3.pl line 30.

Could someone explaine me this behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

錯遇了你 2024-09-11 12:21:05

试试这个

$sth = $dbh->prepare ("SELECT * FROM $table WHERE id =
(选择 MAX( id ) FROM $table)" );

Try this

$sth = $dbh->prepare ( "SELECT * FROM $table WHERE id =
(select MAX( id ) FROM $table)" );

冰火雁神 2024-09-11 12:21:05

我今天看到类似的事情发生。我发现如果我这样做:

    my $foo = $dbh->prepare("SELECT * FROM $table");
    if($foo) {
       $foo->finish();
    }
    #run your prepare here

直接在使用 UDF 或函数的查询之前,错误就会消失......我就这么做了:)

I saw something similar to this occur today. I found that if I did:

    my $foo = $dbh->prepare("SELECT * FROM $table");
    if($foo) {
       $foo->finish();
    }
    #run your prepare here

directly before the query that used a UDF or function, the error went away...I went with it :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文