2

有人可以协助纠正这段代码中的错误。

(这只是我的代码的简化版本,但它确定了问题)。

DROP FUNCTION perl_func(VARIADIC params character varying[]);

CREATE OR REPLACE FUNCTION perl_func(VARIADIC params character varying[])
  RETURNS character varying AS
$BODY$   
   $val = spi_query("array_to_string($1,'###');");
   $s = `echo $val`;
   return $s; 
$BODY$
  LANGUAGE plperlu VOLATILE
  COST 100;

SELECT * from perl_func('a','d');

这会返回一个语法错误:

ERROR:  syntax error at or near "," at line 2.
CONTEXT:  PL/Perl function “perl_func”

主要目的:是将输入参数制定为字符串,并用它来调用一些命令行程序,该程序返回一个字符串。然后输出这个字符串作为这个函数的返回值。

4

1 回答 1

0

原始尝试:

该变量$1在 Perl 中的含义与在 plpgsql 函数中的含义不同。尝试

CREATE OR REPLACE FUNCTION perl_func(VARIADIC params character varying[])
  RETURNS character varying AS
$BODY$
   use strict;
   use warnings;
   my $val = join("###",@_);
   my $s = `echo $val`;
   chomp($s);
   return $s; 
$BODY$
  LANGUAGE plperlu VOLATILE
  COST 100;

不幸的是,这不起作用(如下所述),因为它没有正确拆分字符串。不幸的是,plperl 认为参数是单个字符串:

CREATE OR REPLACE FUNCTION perl_str(VARIADIC text[])
  RETURNS text AS
$BODY$
   use strict;
   use warnings;
   my $array_str=shift;
   return $array_str;
$BODY$
  LANGUAGE plperl VOLATILE;

当我们选择它时:

> select perl_str(ARRAY['abc','def']);
 perl_str
-----------
 {abc,def}
(1 row)

为了确定它是一个字符串,我们可以求助于我们的老朋友Data::Dumper

CREATE OR REPLACE FUNCTION perl_dump(VARIADIC text[])
  RETURNS text AS
$BODY$
   use strict;
   use warnings;
   use Data::Dumper;
   my $array_str=shift;
   return Dumper($array_str);
$BODY$
  LANGUAGE plperl VOLATILE; 

这会返回:

> select perl_dump(ARRAY['abc','def']);
      perl_dump
----------------------
 $VAR1 = '{abc,def}';

(1 row)

因此,输出被认为是一个实际的字符串,末尾带有花括号,条目用逗号分隔。好吧,好吧……这很烦人,但至少我们可以处理它:

CREATE OR REPLACE FUNCTION final_perl_func(VARIADIC text[])
  RETURNS text AS
$BODY$
   use strict;
   use warnings;
   my $array_string=shift;
   $array_string=substr($array_string,1,length($array_string)-2);
   my @array=split(/,/,$array_string);
   my $val=join("###",@array);
   my $s=`echo $val`;
   chomp($s);
   return $s;
$BODY$
  LANGUAGE plperl VOLATILE;

这得到了我们想要的:

> select final_perl_func(ARRAY['abc','def']);
 final_perl_func
-----------------
 abc###def
(1 row)

请注意,由于我不明白的原因,我不得不求助于使用substr而不是简单的正则表达式替换($array_string=~s/{}//g;),因为当我尝试正则表达式替换时,plperl 函数不断返回大括号。

在回答您有关它的问题之前,我没有处理过很多 plperl 问题,而我学到的主要内容是它是一个主要的痛苦……您可能需要考虑使用PerlDBI从 Perl 操作数据库。

于 2012-04-18T16:11:09.133 回答