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)

理解できない理由で、正規表現の置換を試みたときにplperl関数が中括弧を返し続けたsubstrため、単純な正規表現の置換()の代わりに使用する必要があったことに注意してください。$array_string=~s/{}//g;

私はそれについてのあなたの質問に答える前にplperlをあまり扱っていませんでした、そして私が学んだ主なことはそれが大きな苦痛であるということです...あなたはPerlを使ってPerlDBIからデータベースを操作することを検討したいかもしれません。

于 2012-04-18T16:11:09.133 に答える