2

I am trying to work with UDFs, defined through SQL::Statement::Functions in Perl with a mySQL database in the backend. I am playing it by the book, as stated in http://metacpan.org/pod/SQL::Statement::Functions#User-Defined-Functions, however, before I even leave square one, an error in the CREATE FUNCTION statement is rearing its ugly head. Here's the code first ($dbh is a given and works fine, it is just part of a bigger construct of the framework I am working with, so I don't want to spam my question with all of it; if I replace foo() in the SELECT by 22, or by "_PK FROM locations", all is good and I get a 22 or a value corresponding to the query in Data::Dumper, so, the connection is ok):

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

sub foo {
    return 999;
}

#$dbh is defined elsewhere
$dbh->do("CREATE FUNCTION foo") or die "error creating function foo(); " . $dbh->errstr;

my $sth = $dbh->prepare("SELECT foo(22)") or die "error preparing query: " . $dbh->errstr;
$sth->execute or die "error executing query: " . $sth->errstr;

my $row = $sth->fetchrow_arrayref();
print "ROW " . Dumper($row);

The error message reads as follows: error creating function foo(); You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1, refering to the $dbh->do("CREATE...") line.

I have tried to dumb the CREATE FUNCTION part down as much as possible, but I also tried it with ...foo EXTERNAL and ...foo EXTERNAL NAME foo as suggested by the manual. Heck, I even created a package for the function, to no avail.

Any ideas what I am doing wrong here?

I checked, and the user I am connected to the database with does have all privileges, including alter_routine_priv and create_routine_priv, if that is what SQL::Statement is using.

4

1 回答 1

1

您没有按预期使用该模块。它是 DBD 用来实现 SQL 语法和函数的 SQL::Parser 模块的扩展。该文档指出:

该模块包含 SQL::Parser 和 SQL::Statement 的内置函数。所有这些功能也可在任何子类化这些模块的 DBD 中使用(例如 DBD::CSV、DBD::DBM、DBD::File、DBD::AnyData、DBD::Excel 等)。

对我来说,这听起来与 mysql 无关。DBD::mysql 用作真实 mysql 数据库的包装器。它只是连接、转发查询、准备它们等等。但是,它不会解析它们。这就是数据库正在做的事情,就像您要连接到 Oracle 或 MSSQL 数据库一样。在这些情况下,驱动程序就像一个 API 包装器。

另一方面,DBD::CSV 和上面提到的其他人正在自己解析 sql。DBD::CSV 打开一个 CSV 文件,理解 SQL 并(非常简单地描述)将其转换为 Perl 代码以在 CSV 数据中查找内容。其他人也是如此。他们使用 SQL::Parser 来理解 SQL。SQL::Statement::Functions 似乎是为 SQL 提供等效 Perl 函数的模块。

当直接使用 SQL::Statement/SQL::Parser 解析 SQL ...

于 2013-08-19T17:48:57.133 回答