Postgres 6.3 ¹öÁ¯ ºÎÅÍ PostgreSQLÀº procedural Language(PL)¸¦ Áö¿øÇϱ⠽ÃÀÛÇß´Ù. ÀÌ°ÍÀº PostgreSQL¸¸ÀÇ Æ¯º°ÇÑ °æ¿ì·Î¼ oracle ÀÇ PL/SQL°ú ºñÀ¯µÉ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ Ư¼öÇÑ ¾ð¾îÀÎ PostgreSQLÀÇ PLÀº PostgreSQL¿¡ ³»ÀåµÈ°Í ¾Æ´Ï°í ¸ðµâÈµÈ Handler¸¦ ´Ù½Ã µ¥ÀÌŸº£À̽º¿¡ µî·ÏÀ» ÇØÁÖ¾î¾ß ÇÑ´Ù. ±×·¸Áö ¾ÊÀ¸¸é µ¥ÀÌŸº£À̽º´Â PL ·Î ¾² ¿©Áø functionÀÇ ³»¿ëÀ» ÀÌÇØÇÒ ¼ö ¾øÀ» °ÍÀÌ´Ù. °á·ÐÀûÀ¸·Î 󸮱â´Â °øÀ¯°´Ã¼·Î¼ ÄÄÆÄÀÏµÇ¸ç µ¿ÀûÀ¸·Î Load µÇ´Â Ưº°ÇÑ ¾ð¾î ó¸® ±â´ÉÀÌ´Ù.
¿©±â¼´Â PL HandlerÀÇ µî·ÏÀÇ ¿¹·Î¼ PLÀÇ ÇÑÁ¾·ùÀÎ PL/pgSQL ¾ð¾î¸¦ µî·ÏÇÏ°Ú´Ù.
°øÀ¯°´Ã¼ÀΠ󸮱â´Â ÄÄÆÄÀÏµÈ ÈÄ ÀνºÅçµÇ¾î¾ß Çϴµ¥ µðÆúÆ®·Î PL/pgSQL Àº PostgreSQL ¼³Ä¡½Ã ÀÚµ¿À¸·Î ÄÄÆÄÀϵÈÈÄ ¶óÀ̺귯¸® µð·ºÅ丮¿¡ ³õ¿©Áø´Ù. ´Ù ¸¥ 󸮱âÀÎ PL/Tcl Àº PostgreSQL ÄÄÆÄÀϽà ¸í½ÃÀûÀ¸·Î ¼³Á¤µÇ¾î¾ßÁö¸¸ ÄÄÆÄ ÀÏµÇ¸ç ¶óÀ̺귯¸® µð·ºÅ丮¿¡ ³õ¿©Áø´Ù. ¶óÀ̺귯¸® µð·ºÅ丮´Â ¼³Ä¡µÇ¾îÁú PostgreSQLÀÇ ¹Ù·Î ¹ØÀÇ lib ÀÌ´Ù. ¿¹¸¦ µé¾î PostgreSQLÀÇ Àý´ë°æ·Î°¡ ´ÙÀ½°ú °°´Ù°í ÇÏÀÚ.
/usr/local/pgsql
±×·¯¸é ¶óÀ̺귯¸® µð·ºÅ丮ÀÇ Àý´ë°æ·Î´Â ´ÙÀ½°ú °°´Ù.
/usr/local/pgsql/lib
PL/pgSQL ¾ð¾î 󸮱⸦ ¼³Ä¡Çϱâ À§Çؼ´Â ¸ÕÀú À§ÀÇ ¶óÀ̺귯¸® µð·ºÅ丮¿¡¼ "plpgsql.so" ¸¦ ¸ÕÀú È®ÀÎÇÏ¿©¾ß ÇÑ´Ù.
È®ÀÎ ÈÄ CREATE FUNCTION ¿Í CREATE PROCEDURAL LANGUAGE ¿¡ ÀÇÇØ °¢ µ¥ÀÌŸº£À̽º ¿¡¼ µî·ÏÀ» ÇÏ¿©¾ß ÇÑ´Ù. °¢ µ¥ÀÌŸº£À̽º¿¡¼ µî·ÏÀ» ÇÏÁö¾Ê°í ÀÏ°ýÀûÀ¸·Î ó¸®ÇÏ°í ½Í´Ù¸é PostgreSQL ÀÇ Æ¯º°Èù µ¥ÀÌŸº£À̽ºÀÎ "template1" ¿¡¼ µî·ÏÀ» ÇϸéµÈ´Ù. template1 ¿¡¼ µî·ÏÀÌ µÇ¾ú´Ù¸é Â÷ÈÄ »ý¼ºµÇ´Â µ¥ÀÌŸº£À̽º¿¡´Â ÀÚµ¿ÀûÀ¸·Î 󸮱Ⱑ µî·ÏµÈ´Ù.
[postgres@nogadax postgresql]psql template1
template1=>
template1=> CREATE FUNCTION plpgsql_call_handler() RETURNS OPAQUE
template1-> AS ' /usr/local/pgsql/lib/plpgsql.so '
template1-> LANGUAGE 'C' ;
template1=>
template1=> CREATE TRUSTED PROCEDURAL LANGUAGE 'plpgsql'
template1-> HANDLER plpgsql_call_handler
template1-> LANCOMPILER 'PL/pgSQL' ;
template1=>
template1=> CREATE DATABASE nogadax ;
template1=>
ȤÀº À§ÀÇ ¹®À» ÈÀÏ·Î ÀúÀåÇÑÈÄ \i ¸¦ »ç¿ëÇÒ ¼ö ÀÖ´Ù.
template1=> \i /usr/local/src/plsql_inst.sql
"CREATE TRUSTED PROCEDURAL LANGUAGE" ¿¡¼ TRUSTED Å°¿öµå´Â PostgreSQL ÀÇ ½´ÆÛÀ¯Àú ±ÇÇÑÀÌ ¾ø´Â ÀÏ¹Ý À¯Àú°¡ "CREATE FUNCTION" À̳ª "CREATE TRIGGER" ¹®À» »ç¿ëÇÒ ¶§ µî·Ï µÈ procedure language(PL) ¸¦ »ç¿ëÇÒ ¼ö ÀÖµµ·Ï ÇØÁØ´Ù.
PL/pgSQL Àº PostgreSQL µ¥ÀÌŸº£À̽º ½Ã½ºÅÛ¿¡¼ "Loadable Procedural Language"ÀÌ´Ù. ÀÌ ÆÐÅ°Áö´Â Jan Wieck ¿¡ÀÇÇØ ÀÛ¼ºµÇ¾ú´Ù.
1. PL/pgSQL Àº function À̳ª trigger procedure ¸¦ ¸¸µå´Âµ¥ »ç¿ëµÇ¾î Áú ¼ö ÀÖ´Ù.
2. SQL ¹®¿¡ Á¦¾î ±¸Á¶¸¦ Ãß°¡ÇÒ ¼ö ÀÖ´Ù.
3. º¹ÀâÇÑ °è»êÀ» ±¸ÇöÇÒ ¼ö ÀÖ´Ù.
4. user°¡ Á¤ÀÇÇÑ Type, Function, OperationÀ» »ó¼ÓÇÒ ¼ö ÀÖ´Ù.
5. Server ¿¡ ÀÇÇØ Trusted(Authentication °ü·ÃÀÇ ¶æ)µÈ°ÍÀ» Á¤ÀÇÇÒ ¼ö ÀÖ´Ù.
6. »ç¿ëÇϱ⠽±´Ù.
PL/pgSQL Àº ´ë¼Ò¹®ÀÚÀÇ ±¸ºÐÀÌ ¾øÀ¸¹Ç·Î Å°¿öµå³ª Identifier µéÀº ´ë¼Ò¹®ÀÚ
±¸ºÐ¾øÀÌ È¥¿ëµÇ¾î ¾²ÀÏ ¼ö ÀÖ´Ù.
PL/pgSQL Àº ºí·° ÁöÇâ¾ð¾îÀÌ´Ù. ºí·°Àº ´ÙÀ½Ã³·³ Á¤ÀǵǾîÁø´Ù.
[ Label ]
[ DECLARE declarations ]
BEGIN
statements
END;
ºí·°ÀÇ statements±¸¿ª³»¿¡ ¿©·¯°³ÀÇ sub-blockÀÌ »ý¼ºµÉ ¼ö ÀÖÀ¸¸ç ÀÌ´Â ¼ºêºí·°³»ÀÇ º¯¼ö µéÀ» ¼ºêºí·° ¿ÜºÎ·ÎºÎÅÍ ¼û±â±â À§ÇØ »ç¿ëµÇ¾îÁú¼ö ÀÖ´Ù. ºí·° ¾ÕºÎºÐÀÇ declarations±¸¿ª ¿¡¼ ¼±¾ðµÈ º¯¼ö´Â function ÀÌ È£ÃâµÉ ¶§ ´ÜÁö Çѹø ÃʱâÈ°¡ µÇ´Â °ÍÀÌ ¾Æ´Ï¶ó ºí·°À¸·Î ÁøÀÔÇÒ ¶§¸¶´Ù ¸Å¹ø µðÆúÆ® °ªÀ¸·Î ÃʱâȵȴÙ.
PL/pgSQL ÀÇ BEGIN/END ¿Í Transaction(BEGIN; END;)À» À§ÇÑ µ¥ÀÌŸº£À̽ºÀÇ ¸í·É¹®°ú´Â ´Ù¸£´Ù´Â°ÍÀ» ÀÌÇØÇØ¾ß ÇÑ´Ù. ¶ÇÇÑ Function°ú Trigger Procedure ¿¡¼´Â Æ®·£Àè¼ÇÀ» ½ÃÀÛ Çϰųª commit À» ÇÒ ¼ö ¾ø°í Postgres´Â ÁßøµÈ Æ®·£Àè¼ÇÀ» °¡Áú ¼ö ¾ø´Ù.
-- : ÇÑ ¶óÀÎÀÇ ÁÖ¼®Ã³¸®
/* */ : ºí·° ´ÜÀ§ ÁÖ¼® ó¸®
CREATE FUNCTION logfunc2(text,text,text) RETURNS datetime
AS '
DECLARE logtxt1 ALIAS FOR $1;
logtxt2 ALIAS FOR $2;
logtxt2 ALIAS FOR $3;
curtime datetime;
BEGIN
curtime :=''now'';
INSERT INTO logtable VALUES (logtxt1,logtxt2,logtxt3,curtime);
RETURN curtime;
END;
' LANGUAGE 'plpgsql';
$1,$2,$3 Àº ÇÔ¼öÀÇ ÀÎÀÚµé·Î¼ ³ª¿µÈ ¼ø¼·Î¼ ÂüÁ¶µÇ¾îÁø´Ù. DECLARE ÀÇ ALIAS FOR º¯¼ö $1 ¿¡ ´ëÇÑ º°¸íÀ» ¼³Á¤ÇÑ´Ù. À̷μ $1 ¿¡ ´ëÇÑ °¡µ¶¼ºÀÌ ³ô¾ÆÁú¼ö ÀÖ´Ù. curtime := ''now''; ´Â º¯¼ö curtime¿¡ ÇöÀçÀÇ ½Ã°¢°ªÀ»(''now'') ÇÒ´çÇÑ´Ù.":=" Àº º¯¼ö¿¡ °ªÀ» ÇÒ´çÇÒ¶§ ¾²ÀδÙ. ¸¶Áö¸·À¸·Î À§ÀÇ ÇÔ¼öÀÇ ¸®ÅÏ°ªÀÌ datetime À̹ǷΠdatetime ŸÀÔÀÇ º¯¼ö curtime À» ¸®ÅÏÇÏ°Ô µÈ´Ù.
´ÙÀ½Àº ¿¹Á¦ÀÔ´Ï´Ù. Àû´çÈ÷ ÈÀÏ·Î º¹»çÇؼ ½ÇÇàÀ» ÇÏ¸é µË´Ï´Ù.
DROP FUNCTION test1();
DROP TABLE tab1;
CREATE TABLE tab1 (
id int4,
name text
);
CREATE FUNCTION test1() RETURNS int4
AS '
DECLARE
var1 tab1.id%TYPE:=1;
var2 tab1.name%TYPE;
var3 var2%TYPE:=''nogada'';
BEGIN
INSERT INTO tab1(id,name) VALUES(var1,var3);
RETURN var1;
END;
' LANGUAGE 'plpgsql';
SELECT test1();
SELECT * FROM tab1;
À§ÀÇ ¿¹Á¦´Â DROP¸í·É¹®À¸·ÎºÎÅÍ ½ÃÀÛÇÑ´Ù. º°´Ù¸¥ ÀÌÀ¯´Â ¾ø°í ¾ÈÀüÇÑ Å×½ºÆ®¸¦ À§ÇØ ±âÁ¸¿¡ ÀÖÀ»Áö ¸ð¸¦ functionÀ̳ª table À» ¸ÕÀú »èÁ¦ÇÑ´Ù. DROP ¸í·É¾î·Î ÀÎÇÑ ¿¡·¯´Â ¹«½ÃÇصµ µÈ´Ù.FunctionÀÇ DECLARE ºÎºÐÀº º¯¼öÀÇ ¼±¾ð ±¸¿ªÀ¸·Î º¸¸é µÇ°Ú´Ù. var1 , var2,var3Àº º¯¼ö¸íÀÌ´Ù. tab.id%TYPE Àº var1 ÀÇ º¯¼öÇüÀ¸·Î¼ tab.id ÀÇ ¼Ó¼ºÀ» ÂüÁ¶Çϸç À̼ӼºÀÇ ¹Ù·Î µÚÀÇ %TYPE ¿¡ÀÇÇØ ÁöÁ¤µÈ´Ù. ¶ÇÇÑ %TYPE Àº ¾ÕÀü¿¡ ¼±¾ðµÈ º¯¼öÀÇ ÀÚ·ãÇüÀ» ÂüÁ¶ ÇÒ ¼ö ÀÖ´Ù. var3 ´Â ¹Ù·Î Àü¿¡ ¼±¾ðµÈ var2 ÀÇ ÀÚ·áÇüÀ» ÂüÁ¶ÇÑ´Ù.
PL/pgSQL Àº Æ®¸®°Å ÇÁ·Î½ÃÁ®¸¦ Á¤ÀÇÇϴµ¥ »ç¿ëµÇ¾îÁú ¼ö Àִµ¥ CREATE FUNCTION¹®À» »ç¿ë ÇÏ¿© »ý¼ºµÇ¾îÁø´Ù. »ý¼ºµÉ Æ®¸®°Å ÇÁ·Î½ÃÁ®´Â ´ëü·Î ÀÎÀÚ°¡¾ø°í opaqueÇüÀ» ¸®ÅÏÇÏ´Â ÇÔ¼ö ·Î¼ »ý¼ºµÇ¾îÁø´Ù.
Æ®¸®°Å ÇÁ·Î½ÃÁ®·Î¼ »ý¼ºµÈ ÇÔ¼ö¿¡´Â ¾à°£ÀÇ Æ¯¼öÇÑ º¯¼ö¸¦ °¡Áö¸ç ÀÌ´Â ÀÚµ¿À¸·Î »ý¼ºµÇ¾î Áö¸ç ´ÙÀ½°ú °°´Ù.
NEW : ROW ·¹º§ Æ®¸®°Å»ó¿¡¼ INSERT/UPDATE ·Î ÀÎÇØ »õ·Î¸® »ý¼ºµÈ
ROW ¸¦ À¯ÁöÇÏ´Â º¯¼ö·Î¼ µ¥ÀÌŸŸÀÔÀº RECORD ÀÌ´Ù. RECORD
ÇüÀº ¹Ì¸® ±¸Á¶ÈµÇÁö ¾ÊÀº ROWTYPE·Î¼ selectionÀ̳ª insert
,update ½Ã °á°ú·Î »ý¼ºµÈ ÇϳªÀÇ row ¸¦ À¯ÁöÇÏ´Â ÇüÀÌ´Ù.
OLD : new ¿Í ´ëÁ¶µÇ´Â º¯¼ö·Î¼ UPDATE³ª DELETEÇü À¸·Î ÀÎÇØ º¯°æ
µÇ±â ÀüÀÇ ROW¸¦ À¯ÁöÇÏ´Â º¯¼öÀÌ´Ù.
TG_NAME : µ¥ÀÌŸ ŸÀÔÀº NAME ÀÌ°í ½ÇÁ¦·Î ±âµ¿µÈ Æ®¸®°ÅÀÇ À̸§¿¡ ´ëÇÑ
º¯¼öÀÌ´Ù.
TG_WHEN : textÇüÀÌ°í BEFORE³ª AFTER¸¦ °¡Áø´Ù.
TG_LEVEL : textÇüÀÌ°í ROW³ª STATEMENT¸¦ °¡Áø´Ù.
TG_OP : textÇüÀÌ°í INSERT³ª UPDATE³ª DELETE ¸¦ °¡Áø´Ù.
TG_RELID : oidÇüÀÌ°í(Object ID) Æ®¸®°Å¸¦ ±âµ¿½ÃÅ°´Â Å×À̺íÀÇ Object ID
ÀÌ´Ù.
TG_RELNAME : nameÇüÀÌ°í Æ®¸®°Å¸¦ ±âµ¿½ÃÅ°´Â Å×À̺íÀÇ name À» °¡Áö´Â º¯¼ö
ÀÌ´Ù.
TG_NARGS : IntegerÇüÀÌ°í Æ®¸®°Å ÇÁ·Î½ÃÁ®¿¡ ÁÖ¾îÁö´Â ÀÎÀÚÀÇ °³¼öÀÌ´Ù.
TG_ARGV[] : array of text ÇüÀÌ°í Æ®¸®°Å ÇÁ·Î½ÃÁ®¿¡ ÁÖ¾îÁö´Â ÀÎÀÚµéÀ»
°ªÀ¸·Î °¡Áö´Â ÅؽºÆ® ¹è¿ÇüÀÇ º¯¼öÀÌ´Ù.
´ÙÀ½À» ÈÀÏ·Î ¸¸µé¾î ½ÇÇàÇغ¸¼¼¿ä.
-------------------------------------------------------Cut here !!
DROP TRIGGER emp_stamp ON emp;
DROP FUNCTION emp_stamp() ;
DROP TABLE emp;
CREATE TABLE emp(
empname text,
salary int4,
last_date datetime,
last_user name
);
CREATE FUNCTION emp_stamp() RETURNS OPAQUE
AS '
BEGIN
IF NEW.empname ISNULL THEN
RAISE EXCEPTION ''empname cannot be NULL value'';
END IF;
IF NEW.salary ISNULL THEN
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname ;
END IF;
IF NEW.salary < 0 THEN
RAISE NOTICE ''% cannot have a negative salary'', NEW.empname ;
END IF;
--NOTICE TEST
RAISE NOTICE ''TRIGGER NAME : %'',TG_NAME ;
RAISE NOTICE ''TRIGGER LEVEL : % TRIGGER OPERATION : %'',TG_LEVEL , TG_OP;
--EXCEPTION TEST
RAISE EXCEPTION ''TRIGGER WHEN : %'',TG_WHEN;
RAISE NOTICE ''TRIGGER LEVEL : % TRIGGER OPERATION : %'',TG_LEVEL , TG_OP;
NEW.last_date := ''now'';
NEW.last_user := getpgusername();
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER emp_stamp AFTER INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
INSERT INTO emp(empname,salary) VALUES('nogadax',20);
INSERT INTO emp(empname) VALUES('winob');
INSERT INTO emp(salary) VALUES(10);
INSERT INTO emp(empname,salary) VALUES('diver',30);
INSERT INTO emp(salary) VALUES(-20);
SELECT * FROM emp;
--------------------------------------------------------------------------End !!
RAISE´Â ¸Þ½ÃÁö¸¦ ´øÁö´Â °ÍÀÔ´Ï´Ù. EXCEEPTIONÀº Æ÷½ºÆ®±×·¹½ºÀÇ DEBUG·¹º§·Î¼ µ¥ÀÌŸº£À̽º¿¡ log ¸¦ ³²±â°í Æ®·£Àè¼ÇÀ» ÁßÁöÇÑ´Ù. ´Ù¸¥ Å°¿öµå·Î NOTICE°¡ ÀÖ ´Âµ¥ ÀÌ°ÍÀº µ¥ÀÌŸº£À̽º¸¦ ÀÛ¼ºÇÏ°í À̸¦ Ŭ¶óÀ̾ðÆ®ÃøÀ¸·Îµµ Àü¼ÛÇÑ´Ù.
RAISE EXCEPTION ''% cannot have NULL salary'', NEW.empname ;
À§ÀÇ ¹®¿¡¼ '' ¿Í '' »çÀÌÀÇ % ´Â NEW.empname ÀÇ °ªÀ» Ãâ·ÂÇÑ´Ù.
CREATE TRIGGER emp_stamp AFTER INSERT OR UPDATE ON emp
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
NEW.empnameÀÇ NEW´Â RECORDŸÀÔÀ¸·Î¼ Æ®¸®°ÅÀÇ À̺¥Æ®ÀÇ ¿øÀÎÀÌ µÇ´Â emp ÀÇ ±¸Á¶¸¦ °¡Áö¸ç NEW ÀÇ °ªÀº eventÀÇ °á°ú·Î¼ Ãß°¡µÇ°Å³ª º¯°æµÈ ÇàÀ» °¡Áø´Ù.
example )
DECLARE
var_a int4 DEFAULT 5;
--var_a º¯¼öÀÇ DEFAULTÀÇ °ªÀº 5ÀÌ´Ù.
example )
DECLARE
var_a test_table%ROWTYPE;
var_a º¯¼ö´Â test_table ÀÇ Å×ÀÌºí ±¸Á¶¸¦ °¡Áø´Ù.
example )
DECLARE
var_a RECORD ;
ƯÁ¤ Å×À̺íÀÇ ±¸Á¶¸¦ °¡ÁöÁö ¾Ê°í selection ÀÇ °á°ú¿¡
´ëÇÑ ±¸Á¶¸¦ °¡Áú ¼ö ÀÖ´Ù.(NEW,OLD)§
$n ¿¡ ´ëÇÑ º°Äª
oldname¸¦ newname·Î ¹Ù²Þ
Postgres-BaseType : Æ÷½ºÆ® ±×·¹½ºÀÇ ±âº» ÀÚ·áÇü( int4,integer,text,char,..)
variable%TYPE
class.field%TYPE
Select expression
identifier :=expression;
SELECT expressions INTO target FROM ...
PERFORM query : Calling another function
RETURN expression;
RAISE [NOTICE | EXCEPTION] '' message % '',variable
IF expression THEN
statements
[ELSE statements]
END IF;
[label]
LOOP statements END LOOP;
[label]
WHILE expression LOOP statements END LOOP;
[label]
FOR name IN [REVERSE] expression LOOP statements END LOOP;
[label]
FOR record | row IN select_clause LOOP statement
END LOOP;
EXIT [label] [WHEN expression];