从PL / Perl代码访问数据库

时间:2012-04-18 16:05:32

标签: perl postgresql plperl

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

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

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”

主要目的:是将输入参数表示为字符串,并使用它来调用一些返回String的命令行程序。然后输出此字符串作为此函数的返回。

1 个答案:

答案 0 :(得分: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,而且我学到的主要内容是它是一个很大的痛苦...你可能想考虑使用{{从Perl操纵数据库' 3}}