PostgreSQL提供內嵌 Perl、Python ... 等 Script 作為它的 Stored Function,稱作 PL/Perl、PL/Python ...。在此演練一個 PL/Perl 的例子。
在此之前,在這裡先描述一下,PostgreSQL 的擴充模組 Procedural Language(PL/***)。它的設計理念是只為資料庫增加一般程式語言的撰寫風格。因此預設狀況下,這些 PL/*** 只能接觸到資料庫裡面的物件,無法跨出資料庫程序可控制的外部環境,像是存取作業系統目錄、寄一封信之類的。
然而,在 PostgreSQL 裡還是能夠用 PL/*** 「接觸」外面的;這些 Procedural Language,在 PostgreSQL 的術語,被稱為 Untrusted Language,例如 PL/PerlU,而這些 Untrusted Language 這基本上就是完全功能的 Perl 了。
由於 Untrusted Language 能存取外部環境,所以只有資料庫的 Super User 帳戶才能執行這些 Untrusted Language。
下面的小小練習,便把一般 Perl Script 以及相對應的 PL/PerlU Script 相互對照。
一般 Perl 版本
sudo yum install perl-DBD-Pg
vi testperl.pl
|
#!/usr/bin/perl
# Prerequisite: Connect to PostgreSQL
use DBI;
my $dbname = "postgres";
my $dbhost = "localhost";
my $dbuser = "postgres";
my $dbpass = "postgres";
$dbh = DBI->connect("dbi:Pg:dbname=$dbname;host=$dbhost", $dbuser, $dbpass) || die "Unale to connect $dbname: $DBI::errstr\n";
# Test1: call module
use Data::Dumper;
my %dmp = ('a1' => 123, 'b2' => [3,2,1]);
print Dumper(\%dmp);
# Test2: Open file and write something
open(MYFILE,">>/tmp/out.log");
print MYFILE time()."Hello".$ARGV[0]."\n";
# Test3: DML into Postgres
my $sSql="INSERT INTO testab VALUES('$ARGV[1]','$ARGV[0]')";
my $sth = $dbh->prepare("$sSql");
$sth->execute;
$sth->finish;
close MYFILE;
$dbh->disconnect;
# Perl code end
|
PL/PerlU 版本
postgres=# CREATE EXTENSION plperlu;
postgres=# \e
|
CREATE OR REPLACE FUNCTION testperl(tst TEXT,nmb INT)
RETURNS void AS $$
# Beginning the Perl code
# Test1: call outside module
use Data::Dumper;
my %dmp = ('a1' => 123, 'b2' => [3,2,1]);
print Dumper(\%dmp);
# Test2: Open file and write something
open(MYFILE,">>/tmp/out.log");
print MYFILE time()."Hello".$_[0]."\n";
# Test3: DML into Postgres
my $sSql="INSERT INTO testab VALUES('$_[1]','$_[0]')";
my $sth = spi_exec_query("$sSql");
close MYFILE;
# Perl code end
$$ LANGUAGE plperlu;
|
postgres=# CREATE TABLE testab(nmb INT, cntxt TEXT);
postgres=# SELECT testperl('Hello, Goodbye',3);
|
在上面這個 PL/PerlU 裡面,試驗了(1) 呼叫外部模組 (2) 開檔案讀寫 (3) 插入資料到 PostgreSQL 裡面 (4) 吃參數進去。
以上可見,PL/PerlU 就是可以在 PostgreSQL 裡面直接用 SELECT 指令呼叫的 Perl Script。上面兩個 Script 間的差別幾乎僅在存取資料庫物件的方式的差異而已。
沒有留言:
張貼留言