2012-04-18 33 views
2

有人請協助糾正這段代碼中的錯誤。來自PL/Perl代碼的數據庫訪問

(這只是我的代碼的簡化版本,但它確定了問題)。

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」 

主要目的:是制定輸入PARAMS作爲一個字符串,並用它來調用一些命令行程序,它返回一個串。然後輸出這個字符串作爲這個函數的返回值。

回答

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問題,而且我學到的主要事情是這是一個主要的難題......您可能需要考慮使用the Perl DBI從Perl操縱數據庫。

+0

我似乎仍然得到一個語法錯誤:'錯誤:語法錯誤在或接近「array_to_string」在第5行。上下文:PL/Perl函數「perl_func」' – Larry 2012-04-18 16:39:58

+0

也是什麼$ x,它是如何知道哪個屬性是哪個。例如,如果函數簽名看起來像(文本,b文本),我們如何引用每個參數?任何幫助將不勝感激thnx! – Larry 2012-04-18 17:25:04

+0

'$ x'是第一個變量,它是['@ _'](http:/ /移除「](http://perldoc.perl.org/5.12.0/functions/shift.html) /perldoc.perl.org/perlvar.html)。你究竟在做什麼,在這裏?你爲什麼要調用['spi_query'](http://www.postgresql.org/docs/8.2/static/plperl-database。HTML),但不叫'spi_fetchrow'? – 2012-04-18 18:06:54