我注意到,当我使用 DBI 从 Perl 脚本调用 PL/PgSQL 或 PL/Perl 函数时,如果函数中使用了 RAISE NOTICE 或 elog(NOTICE),它不会返回值。举例说明:
一个简单的表格:
CREATE TABLE "public"."table1" (
"fld" INTEGER
) WITHOUT OIDS;
一个简单的功能:
CREATE OR REPLACE FUNCTION "public"."function1" () RETURNS integer AS
$body$
DECLARE
myvar INTEGER;
BEGIN
SELECT INTO myvar fld FROM table1 LIMIT 1;
RETURN myvar;
END;
$body$
LANGUAGE 'plpgsql'
一段Perl脚本:
use DBI;
...
my $ref = $dbh->selectcol_arrayref('SELECT function1()');
print $$ref[0];
实际上,它打印表中的值。
但是如果我按如下方式添加“RAISE NOTICE”,则不会得到任何结果:
SELECT INTO myvar fld FROM table1 LIMIT 1;
RAISE NOTICE 'Testing';
RETURN myvar;
我是否遗漏了某些东西,或者此类行为是有意为之?
检查数据库服务器的 client_min_messages
文件中的
postgresql.conf
设置。来自 PostgreSQL 8.3 文档:
(字符串)client_min_messages
控制发送到客户端的消息级别。有效值为
、DEBUG5
、DEBUG4
、DEBUG3
、DEBUG2
、DEBUG1
、LOG
、NOTICE
、WARNING
、ERROR
和 PANIC。每个级别都包含其后的所有级别。级别越晚,发送的消息越少。默认为FATAL
。请注意,NOTICE
此处的排名与LOG
中的排名不同。log_min_messages
我无法使用 Debian 的 Perl 5.10、DBI 1.605 和 DBD::Pg 2.8.7 与 PostgreSQL 8.3.7 重现这一点。我按预期打印了通知。
steve@steve@[local] =# create or replace function public.function1() returns integer language 'plpgsql' as $$ declare myvar integer; begin select into myvar fld from table1 limit 1; raise notice 'Testing'; return myvar; end; $$;
CREATE FUNCTION
steve@steve@[local] =#
[1]+ Stopped psql --cluster 8.3/steve
steve@arise:~$ DBI_TRACE=1 perl -MData::Dumper -MDBI -e '$dbh = DBI->connect(qw|dbi:Pg:dbname=steve;port=5433;host=/tmp steve steve|, {RaiseError=>1,PrintError=>0}); print Data::Dumper->new([$dbh->selectcol_arrayref("SELECT function1()")], [qw|result|])->Dump'
DBI 1.605-ithread default trace level set to 0x0/1 (pid 5739) at DBI.pm line 273 via -e line 0
Note: perl is running without the recommended perl -w option
-> DBI->connect(dbi:Pg:dbname=steve;port=5433;host=/tmp, steve, ****, HASH(0x1c9ddf0))
-> DBI->install_driver(Pg) for linux perl=5.010000 pid=5739 ruid=1000 euid=1000
install_driver: DBD::Pg version 2.8.7 loaded from /usr/lib/perl5/DBD/Pg.pm
<- install_driver= DBI::dr=HASH(0x1e06a68)
!! warn: 0 CLEARED by call to connect method
<- connect('dbname=steve;port=5433;host=/tmp', 'steve', ...)= DBI::db=HASH(0x1fd8e08) at DBI.pm line 638
<- STORE('RaiseError', 1)= 1 at DBI.pm line 690
<- STORE('PrintError', 0)= 1 at DBI.pm line 690
<- STORE('AutoCommit', 1)= 1 at DBI.pm line 690
<- STORE('Username', 'steve')= 1 at DBI.pm line 693
<> FETCH('Username')= 'steve' ('Username' from cache) at DBI.pm line 693
<- connected('dbi:Pg:dbname=steve;port=5433;host=/tmp', 'steve', ...)= undef at DBI.pm line 699
<- connect= DBI::db=HASH(0x1fd8e08)
<- STORE('dbi_connect_closure', CODE(0x1da2280))= 1 at DBI.pm line 708
NOTICE: Testing
<- selectcol_arrayref('SELECT function1()')= ( [ '2' ] ) [1 items] at -e line 1
$result = [
'2'
];
我建议将您的问题隔离到一个小脚本(如上)并使用
DBI_TRACE
设置相当高的值来运行它,看看您看到了什么差异。也许还可以查看 DBD::Pg 的发行说明,看看他们是否提到它,也许过去曾被这些所困惑。通过 DBI_TRACE=10
我看到了这个:
PQexec
Begin pg_warn (message: NOTICE: Testing
DBIc_WARN: 1 PrintWarn: 1)
NOTICE: Testing
End pg_warn
Begin _sqlstate
所以你应该在自己的输出中寻找类似的东西。
创建或替换函数display_managers() AS $$ 宣布 cur CURSOR FOR SELECT mid,Name FROM EMP WHERE mid IS NOT NULL; 记录记录; 开始 打开当前; 环形 FETCH cur INTO 记录; 未找到时退出; RAISE NOTICE '经理 ID:%,姓名:%',record.mid,record.Name; 结束循环; 关闭当前; 结尾; $$ 语言 plpgsql;
错误:必须指定函数结果类型 SQL状态:42P13