| PostgreSQL 8.3.3¹®¼ | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 39. PL/Perl - Perl ¼ö¼Ó ¾ð¾î | Fast Forward | Next |
Perl ÇÔ¼ö·ÎºÎÅÍÀÇ µ¥ÀÌÅͺ£À̽º Á¢±ÙÀ», ÈļúÀÇ spi_exec_query ȤÀº
DBD::PgSPI
(
CPAN mirror sites
·ÎºÎÅÍ ÀÔ¼ö °¡´É)¶ó´Â
½ÇÇè ´Ü°èÀÇ ¸ðµâ °æÀ¯·Î ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.
ÀÌ ¸ðµâ¿¡ ÀÇÇØ, DBIȣȯÀÇ $pg_dbh¶ó´Â µ¥ÀÌÅͺ£À̽º ÇÚµéÀ» »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.
ÀÌ ÇÚµéÀ» »ç¿ëÇØ, Åë»óÀÇ DBI±¸¹®À» »ç¿ëÇÑ Äõ¸®¸¦ ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.
ÇöÀç, PL/Perl´Â ÀÌÇÏÀÇ º¸Á¶ÀûÀÎ Perl ¸í·É¸¦ Á¦°øÇÕ´Ï´Ù.
spi_exec_query(
query
[,
max-rows
])
spi_query(
command
)
spi_fetchrow(
cursor
)
spi_prepare(
command
,
argument types
)
spi_exec_prepared(
plan
)
spi_query_prepared(
plan
[,
attributes
],
arguments
)
spi_cursor_close(
cursor
)
spi_freeplan(
plan
)
spi_exec_query´Â SQL ¸í·ÉÀ» ½ÇÇàÇØ, Çà ¼¼Æ® Àüü¸¦ ÇØ½Ã¿¡ÀÇ ÂüÁ¶¸¦ ¿ä¼Ò·Î ÇÏ´Â ¹è¿¿¡ÀÇ ÂüÁ¶·Î¼ µ¹·ÁÁÝ´Ï´Ù. °á°ú°¡ »ó´ëÀûÀ¸·Î ¼Ò±Ô¸ðÀÎ °ÍÀ» ¾Ë°í ÀÖ´Â °æ¿ì¿¡°Ô¸¸ ÀÌ ¸í·É¸¦ »ç¿ëÇØ ÁÖ¼¼¿ä. ÀÌÇÏ¿¡ ÃÖ´ëÇà ¿É¼ÇÀ» °¡Áø Äõ¸®(SELECT¸í·É)ÀÇ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.
$rv = spi_exec_query('SELECT * FROM my_table', 5);
À̰ÍÀº my_tableÅ×ÀÌºí¿¡¼ 5Çà±îÁö¸¦ µ¹·ÁÁÝ´Ï´Ù. my_table¿¡ my_column¿ÀÌ ÀÖ´Â °æ¿ì, °á°úÀÇ $iÇàÀÇ ·Ä°ª¸¦ ÀÌÇÏ¿Í °°ÀÌ ²¨³¾ ¼ö°¡ ÀÖ½À´Ï´Ù.
$foo = $rv->{rows}[$i]->{my_column};
SELECTÄõ¸®·ÎºÎÅÍ µ¹·ÁÁÖ¾îÁö´Â ÇàÀÇ ÃѼö´Â ÀÌÇÏ¿Í °°ÀÌ Á¢±Ù ÇÒ ¼ö ÀÖ½À´Ï´Ù.
$nrows = $rv->{processed}
ÀÌÇÏ´Â ´Ù¸¥ Á¾·ùÀÇ ¸í·É¸¦ »ç¿ëÇÏ´Â ¿¹ÀÔ´Ï´Ù.
$query = "INSERT INTO my_table VALUES (1, 'test')"; $rv = spi_exec_query($query);
ÀÌ ÈÄ, ÀÌÇÏ¿Í °°ÀÌ ¸í·É »óÅÂ(¿¹¸¦ µé¸é SPI_OK_INSERT)¿¡ Á¢±Ù ÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.
$res = $rv->{status};
¿µÇâÀ» ¹ÞÀº Çà¼ö¸¦ ²¨³»·Á¸é ÀÌÇϸ¦ ½Ç½ÃÇÕ´Ï´Ù.
$nrows = $rv->{processed};
ÀÌÇÏ¿¡ ¿Ï¼ºµÈ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.
CREATE TABLE test (
i int,
v varchar
);
INSERT INTO test (i, v) VALUES (1, 'first line');
INSERT INTO test (i, v) VALUES (2, 'second line');
INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal');
CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
my $rv = spi_exec_query('select i, v from test;');
my $status = $rv->{status};
my $nrows = $rv->{processed};
foreach my $rn (0 .. $nrows - 1) {
my $row = $rv->{rows}[$rn];
$row->{i} += 200 if defined($row->{i});
$row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
return_next($row);
}
return undef;
$$ LANGUAGE plperl;
SELECT * FROM test_munge();
spi_query ¹× spi_fetchrow´Â, ´ë±Ô¸ð·Î µÉ °¡´É¼ºÀÌ ÀÖ´Â Çà ¼¼Æ®¿ë, ¶Ç´Â, ÇàÀ» Â÷·Ê ´ë·Î¿¡ µ¹·ÁÁÖ°í ½ÍÀº °æ¿ì Àü¿ëÀ¸·Î Á¶ÇÕÇØ µ¿ÀÛÇÕ´Ï´Ù. spi_fetchrow´Â spi_query¿Í ÇÔ²²°¡ ¾Æ´Ï¸é µ¿ÀÛÇÏÁö ¾Ê½À´Ï´Ù. Á¶ÇÕÇØ »ç¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ, ÀÌÇÏÀÇ ¿¹·Î °¡¸®Åµ´Ï´Ù.
CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);
CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
use Digest::MD5 qw(md5_hex);
my $file = '/usr/share/dict/words';
my $t = localtime;
elog(NOTICE, "opening file $file at $t" );
open my $fh, '<', $file # ooh, it's a file access!
or elog(ERROR, "can't open $file for reading: $!");
my @words = <$fh>;
close $fh;
$t = localtime;
elog(NOTICE, "closed file $file at $t");
chomp(@words);
my $row;
my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
while (defined ($row = spi_fetchrow($sth))) {
return_next({
the_num => $row->{a},
the_text => md5_hex($words[rand @words])
});
}
return;
$$ LANGUAGE plperlu;
SELECT * from lotsa_md5(500);
spi_prepare, spi_query_prepared, spi_exec_prepared, spi_freeplan´Â, Áغñ°¡ ³¡³ª Äõ¸®¿ëÀ¸·Î °°Àº ±â´ÉÀ» ±¸ÇöÇÕ´Ï´Ù. spi_prepare¸¦ È£ÃâÇØ Äõ¸® °èȹÀÇ Áغñ°¡ ³¡³ª¸é spi_exec_query¿¡ ÀÇÇØ ¹ÝȯµÈ °Í°ú °°Àº °á°ú°¡ µÇ´Â spi_exec_preparedÀ̳ª spi_query¿Í ¿ÏÀüÈ÷ °°Àº Ä¿¼°¡ ¹ÝȯµÈ spi_query_prepared¸¦ »ç¿ëÇØ, ±× °èȹÀ» ¹®ÀÚ¿ Äõ¸® ´ë½Å¿¡ »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.
Áغñ°¡ ³¡³ Äõ¸®ÀÇ ÀÌÁ¡Àº, 1°³ÀÇ ÁغñµÈ °èȹÀ» ¿©·¯ Â÷·Ê »ç¿ëÇØ Äõ¸®¸¦ ½ÇÇàÇÒ ¼ö°¡ ÀÖ´Ù°í ÇÏ´Â Á¡ÀÔ´Ï´Ù. °èȹÀÌ ºÒÇÊ¿äÇÏ°Ô µÈ ÈÄ, spi_freeplan·Î °³¹æÇÒ ¼ö ÀÖ½À´Ï´Ù.
CREATE OR REPLACE FUNCTION init() RETURNS INTEGER AS $$
$_SHARED{my_plan} = spi_prepare( 'SELECT (now() + $1)::date AS now', 'INTERVAL');
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
return spi_exec_prepared(
$_SHARED{my_plan},
$_[0],
)->{rows}->[0]->{now};
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION done() RETURNS INTEGER AS $$
spi_freeplan( $_SHARED{my_plan});
undef $_SHARED{my_plan};
$$ LANGUAGE plperl;
SELECT init();
SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
SELECT done();
add_time | add_time | add_time
------------+------------+------------
2005-12-10 | 2005-12-11 | 2005-12-12
spi_prepare³»ÀÇ ¸Å°³º¯¼ö ÷ÀÚ°¡ $1,$2,$3µîÀ» °³ÀÔ½ÃÄÑ Á¤ÀǵǴ °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä. ±× ¶§¹®¿¡, Àâ±â Èûµç ¹ö±×°¡ ½±°Ô ¹ß»ýµÇ´Â ÀÌÁß ÀοëºÎÈ£³»¿¡¼ÀÇ Äõ¸® ¼±¾ðÀº ±×¸¸µÎ¾î ÁÖ¼¼¿ä.
Åë»ó spi_fetchrow´Â, Àо´Â ÇàÀÌ ÀÌÁ¦ Á¸ÀçÇÏÁö
¾Ê´Â °ÍÀ» ÀǹÌÇÏ´Â undef°¡ µ¹·ÁÁÖ¾îÁú ¶§±îÁö,
¹Ýº¹µÉ °ÍÀÔ´Ï´Ù.spi_fetchrow°¡ undef
¸¦ µ¹·ÁÁÙ ¶§, Ä¿¼´Â ÀÚµ¿ÀûÀ¸·Î °³¹æµË´Ï´Ù. µ¹¾Æ¿À´Â ¸ðµç ÇàÀ»
Àо Çʿ䰡 ¾øÀ¸¸é, spi_cursor_close¸¦ È£ÃâÇØ
Ä¿¼¸¦ °³¹æÇØ ÁÖ¼¼¿ä. À̰Ϳ¡ ½ÇÆÐÇÏ¸é ¸Þ¸ð¸® ¸®Å©°¡ ¹ß»ýÇÕ´Ï´Ù.
elog(
level
,
msg
)
·Î±× ¶Ç´Â ¿¡·¯ ¸Þ¼¼Áö¸¦ ¹ßÇàÇÕ´Ï´Ù. »ç¿ëÇÒ ¼ö ÀÖ´Â ·¹º§Àº, DEBUG, LOG, INFO, NOTICE, WARNING, ¹× ERRORÀÔ´Ï´Ù. ERROR´Â ¿¡·¯ »óŸ¦ ¹ß»ýÇÕ´Ï´Ù. °Ô´Ù°¡ À§ÀÇ Perl ÄÚµå·Î ÀÌ ¿¡·¯¸¦ Æ÷ÂøÇÏÁö ¾Ê´Â °æ¿ì, ¿¡·¯´Â Äõ¸®ÀÇ È£Ãâ¿ø±îÁö ÀüÆÄ ÇØ, ±× °á°ú, ÇöÀçÀÇ Æ®·£Àè¼Ç ȤÀº ¼ºêÆ®·£Àè¼ÇÀ» Áß´ÜÇÕ´Ï´Ù. À̰ÍÀº ½ÇÁú PerlÀÇdie¸í·É¿Í °°½À´Ï´Ù. ´Ù¸¥ ·¹º§Àº, ´Ù¸¥ Á߿䵵ÀÇ ¸Þ¼¼Áö¸¦ »ý¼ºÇÒ »ÓÀÔ´Ï´Ù. log_min_messages°ú client_min_messages¼³Á¤ ¸Å°³º¯¼ö´Â, ƯÁ¤ÀÇ Á߿䵵ÀÇ ¸Þ¼¼Áö¸¦ Ŭ¶óÀÌ¾ðÆ®¿¡ º¸°íÇϰųª, ¼¹öÀÇ ·Î±×¿¡ ½á³»°Å³ª, ȤÀº ±× ¾çÂÊ ¸ðµÎ¸¦ Á¦¾îÇÕ´Ï´Ù. ÀÚ¼¼ÇÑ °ÍÀº Chapter 17À» ÂüÁ¶ÇØ ÁÖ¼¼¿ä.