33.4. Äõ¸® ¾ð¾î(SQL) ÇÔ¼ö

SQL ÇÔ¼ö´Â, ÀÓÀÇÀÇ SQLÄõ¸® ¸®½ºÆ®¸¦ ½ÇÇàÇØ, ±× ¸®½ºÆ®ÀÇ ¸¶Áö¸· Äõ¸®ÀÇ °á°ú¸¦ µ¹·ÁÁÝ´Ï´Ù. ´Ü¼øÇÑ(ºñÁýÇÕÀÇ) °æ¿ì, ¸¶Áö¸· Äõ¸®ÀÇ °á°úÀÇ ÃÖÃÊÀÇ ÇàÀÌ µ¹·ÁÁÖ¾îÁý´Ï´Ù (º¹¼öÇàÀÇ °á°ú °¡¿îµ¥ "ÃÖÃÊÀÇ Çà"Àº, ORDER BY¸¦ »ç¿ëÇÏÁö ¾Ê´Â ÇÑ ºÙÀÌÁö ¸øÇÏ´Â °ÍÀ» ±â¾ïÇØÁÖ¼¼¿ä). ¸¶Áö¸· Äõ¸®°¡ ¾Æ¹«°Íµµ ÇàÀ» µ¹·ÁÁÖÁö ¾ÊÀ» ¶§´Â NULL°ªÀÌ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

±× ¹Û¿¡µµ, SQL ÇÔ¼ö´Â, SETOF sometype ÇüÀ» µ¹·ÁÁÖµµ·Ï ÁöÁ¤ÇÏ´Â °ÍÀ¸·Î½á, ÁýÇÕÀ» µ¹·ÁÁÖµµ·Ï ¼±¾ðÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ÀÌ °æ¿ì, ¸¶Áö¸· Äõ¸®ÀÇ °á°úÀÇ ¸ðµç ÇàÀÌ µ¹·ÁÁÖ¾îÁý´Ï´Ù. ÀÚ¼¼ÇÑ °ÍÀº ´ÙÀ½¿¡ ¼³¸íÇÕ´Ï´Ù.

SQL ÇÔ¼öÀÇ º»Ã¼´Â, ¼¼¹ÌÄÝ·ÐÀ¸·Î ´Ü¶ôÁöÀº SQL¸í·É¹®ÀÇ ¸®½ºÆ®°¡ ¾Æ´Ï¸é ¾ÈµË´Ï´Ù. ¸¶Áö¸· ¸í·É¹® µÚÀÇ ¼¼¹ÌÄÝ·ÐÀº »ý·« °¡´ÉÇÕ´Ï´Ù. ÇÔ¼ö°¡ void¸¦ µ¹·ÁÁÖµµ·Ï ¼±¾ðµÇ¾î ÀÖÁö ¾ÊÀº ÇÑ, ¸¶Áö¸· ¸í·É¹®Àº SELECT°¡ ¾Æ´Ï¸é ¾ÈµË´Ï´Ù.

SQL¾ð¾î·Î ÀÛ¼ºµÈ, ÀÓÀÇÀÇ ¸í·É ±ºÀº Á¤¸®ÇØ, ÇÔ¼ö·Î¼­ Á¤ÀÇÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. SELECTÄõ¸® ¿Ü¿¡, µ¥ÀÌÅÍ º¯°æ¿ëÀÇ Äõ¸®(Áï, INSERT, UPDATE, DELETE)³ª ±× ¿ÜÀÇ SQL ¸í·ÉÀ» Æ÷ÇÔÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. (¿¹¿Ü°¡ 1°³ÀÖ½À´Ï´Ù. ±×°ÍÀº BEGIN, COMMIT, ROLLBACK, SAVEPOINT¸¦ SQLÇÔ¼ö¿¡ Æ÷ÇÔÇÒ ¼ö ¾ø´Â Á¡ÀÔ´Ï´Ù.) ±×·¯³ª, ¸¶Áö¸· ¸í·ÉÀº, ÇÔ¼öÀÇ ¹Ýȯ°ªÇüÀ¸·Î Á¤ÀÇÇÑ °ÍÀ» µ¹·ÁÁÖ´Â SELECT°¡ ¾Æ´Ï¸é ¾ÈµË´Ï´Ù. ±× ¿Ü¿¡µµ, ¾î¶² µ¿ÀÛÀ» ½ÃŰÁö¸¸, À¯¿ëÇÑ °ªÀ» µ¹·ÁÁÖÁö ¾Ê´Â SQL ÇÔ¼ö¸¦ Á¤ÀÇÇÏ°í ½ÍÀº °ÍÀ̸é, void¸¦ µ¹·ÁÁÖ´Â °ÍÀ̶ó°í Á¤ÀÇÇÏ´Â °ÍÀ¸·Î ½ÇÇö °¡´ÉÇÕ´Ï´Ù. ±× °æ¿ì, ÇÔ¼ö º»Ã¼´Â SELECT·Î ³¡³ªÁö ¾Ê½À´Ï´Ù. ¿¹¸¦ µé¾î, ÀÌÇÏÀÇ ÇÔ¼ö´Â empÅ×ÀÌºí¿¡¼­ ºÎÀÇ ±Þ·á°¡ µÇ°í ÀÖ´Â ÇàÀ» »èÁ¦ÇÕ´Ï´Ù.

CREATE FUNCTION clean_emp() RETURNS void AS '
    DELETE FROM emp
        WHERE salary < 0;
' LANGUAGE SQL;

SELECT clean_emp();

 clean_emp
-----------

(1 row)

CREATE FUNCTION¸í·ÉÀÇ ±¸¹®¿¡¼­´Â, ÇÔ¼ö º»Ã¼´Â ¹®ÀÚ¿­ Á¤¼ö·Î¼­ ÀÛ¼ºµÉ Çʿ䰡 ÀÖ½À´Ï´Ù. ÀÌ ¹®ÀÚ¿­ Á¤¼öÀÇ ±â¼ú¿¡´Â, Åë»ó, ´Þ·¯ ÀοëºÎÈ£¸¦ ºÙÀÌ´Â(Section 4.1.2.2)°ÍÀÌ °¡Àå Æí¸®ÇÕ´Ï´Ù. ¹®ÀÚ¿­ Á¤¼ö¸¦ ´ÜÀÏ ÀοëºÎÈ£·Î °ýÅë»óÀÇ ±¸¹®¿¡¼­´Â, ÇÔ¼ö º»Ã¼Áß¿¡¼­ »ç¿ëµÇ´Â ´ÜÀÏ ÀοëºÎÈ£(')¿Í backslash(\)(À̽ºÄÉÀÌÇÁ ¹®ÀÚ¿­ ±¸¹®À» °¡Á¤)¸¦, ÀϹÝÀûÀ¸·Î, ÀÌ ¹®ÀÚ¸¦ ÀÌÁß ÀοëºÎÈ£ ó¸®ÇÏÁö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù(Section 4.1.2.1¸¦ ÂüÁ¶).

SQL ÇÔ¼öÀÇ ÀÎÀÚ´Â ÇÔ¼ö º»Ã¼³»¿¡¼­ $ n ¶ó°í ÇÏ´Â ±¸¹®À» ÀÌ¿ëÇØ ³ªÅ¸³¾ ¼ö°¡ ÀÖ½À´Ï´Ù. Áï, $1Àº Á¦1 ÀÎÀÚ¸¦ ³ªÅ¸³», $2´Â Á¦2 ÀÎÀÚ¿Í °°ÀÌ µË´Ï´Ù. ÀÎÀÚ°¡ º¹ÇÕÇüÀÎ °æ¿ì, $1. name¿Í °°Àº µµÆ® Ç¥±â¸¦ ÀÌ¿ëÇØ ÀÎÀÚÀÇ ¼Ó¼º¿¡ Á¢±Ù ÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌ ÀÎÀÚ´Â, ½Äº°Àڷμ­°¡ ¾Æ´Ï°í, µ¥ÀÌÅͰªÀ¸·Î º¸°í »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. µû¶ó¼­, ¿¹¸¦ µé¸é

INSERT INTO mytable VALUES ($1);

(Àº)´Â ¿Ã¹Ù¸¥ °ÍÀÔ´Ï´Ù¸¸, ÀÌÇÏ´Â µ¿ÀÛÇÏÁö ¾Ê½À´Ï´Ù.

INSERT INTO $1 VALUES (42);

33.4.1. ±âº»ÇüÀ» »ç¿ëÇÏ´ÂSQLÇÔ¼ö

°¡Àå °£´ÜÇÑ SQLÇÔ¼ö´Â, ÀÎÀÚ¸¦ ÃëÇÏÁö ¾Ê°í ´ÜÁö integer¿Í °°Àº ±âº»ÇüÀ» µ¹·ÁÁÖ´Â °ÍÀÔ´Ï´Ù.

CREATE FUNCTION one() RETURNS integer AS $$
    SELECT 1 AS result;
$$ LANGUAGE SQL;

-- ¹®ÀÚ¿­ ¸®ÅÍ·²ÀÇ ´Ù¸¥ ±¸¹®¿¡¼­´Â
CREATE FUNCTION one() RETURNS integer AS '
    SELECT 1 AS result;
' LANGUAGE SQL;

SELECT one();

 one
-----
   1

ÇÔ¼ö º»Ã¼³»¿¡¼­ ÇÔ¼öÀÇ °á°ú·Î ¿­ÀÇ °¡¸íÀ» (result¶ó´Â À̸§À¸·Î) Á¤ÀÇÇß´ø °Í¿¡ ÁÖ¸ñÇØ ÁÖ¼¼¿ä. ±×·¯³ª ÀÌ ¿­ÀÇ °¡¸íÀº ÀÌ ÇÔ¼ö ¹Û¿¡¼­´Â º¼ ¼ö ¾ø½À´Ï´Ù. µû¶ó¼­, ±× °á°ú´Â result´Â ¾Æ´Ï°í, one¶ó´Â ¶óº§·Î Ç¥½ÃµÇ°í ÀÖ½À´Ï´Ù.

±âº»ÇüÀ» ÀÎÀڷμ­ ÃëÇÏ´Â, SQLÇÔ¼ö¸¦ Á¤ÀÇÇÏ´Â °ÍÀº ´ëºÎºÐÀÇ °æ¿ì °£´ÜÇÕ´Ï´Ù. ÀÌÇÏÀÇ ¿¹¿¡ ´ëÇØ, ÇÔ¼ö ³»ºÎ¿¡¼­ ±× ÀÎÀÚ¸¦ $1°ú $2·Î¼­ Á¢±ÙÇϰí ÀÖ´Â °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä.

CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$
    SELECT $1 + $2;
$$ LANGUAGE SQL;

SELECT add_em(1, 2) AS answer;

 answer
--------
      3

ÀÌÇÏ¿¡ Á» ´õ µµ¿òÀÌ µÇ´Â ÇÔ¼ö¸¦ ³ªÅ¸³À´Ï´Ù. À̰ÍÀº ÀºÇà °èÁ·κÎÅÍ ÀÇ ÀÚµ¿ ³³ºÎ¿¡ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.

CREATE FUNCTION tf1 (integer, numeric) RETURNS integer AS $$
    UPDATE bank 
        SET balance = balance - $2
        WHERE accountno = $1;
    SELECT 1;
$$ LANGUAGE SQL;

ÀÌÇÏ¿Í °°ÀÌ, »ç¿ëÀÚ´Â ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇØ, °èÁ ¹øÈ£ 17¿¡¼­ 100 ´Þ·¯¸¦ ²¨³»´Â °ÍÀÌ °¡´ÉÇÕ´Ï´Ù.

SELECT tf1(17, 100.0);

½ÇÁ¦·Î, ÇÔ¼öÀÇ °á°ú¸¦ Á¤¼ö 1º¸´Ù ¾Ë±â ½¬¿î ÇüÅ·ΠÇϱ⠶§¹®¿¡, ÀÌÇÏ¿Í °°ÀÌ Á¤ÀÇÇϸé ÁÁÀ» °ÍÀÔ´Ï´Ù.

CREATE FUNCTION tf1 (integer, numeric) RETURNS numeric AS $$
    UPDATE bank 
        SET balance = balance - $2
        WHERE accountno = $1;
    SELECT balance FROM bank WHERE accountno = $1;
$$ LANGUAGE SQL;

À̰ÍÀº ÀÜ°í¸¦ Á¶Á¤ÇØ, °»½Å ÈÄÀÇ ÀÜ°í¸¦ µ¹·ÁÁÝ´Ï´Ù.

33.4.2. º¹ÇÕÇüÀ» »ç¿ëÇÏ´ÂSQLÇÔ¼ö

ÇÔ¼öÀÇ ÀÎÀÚ¿¡ º¹ÇÕÇüÀ» ±â¼úÇßÀ» °æ¿ì, (Áö±Ý±îÁö ÇØ¿Â $1¿Í $2¿Í °°ÀÌ) ÇÊ¿äÇÑ ÀÎÀÚ¸¸À» ÁöÁ¤ÇÏ´Â °Í ¸¸ÀÌ ¾Æ´Ï°í, ÇÊ¿ä·Î ÇÏ´Â ÀÎÀÚÀÇ ¼Ó¼º(Çʵå)µµ ÁöÁ¤ÇÒ Çʿ䰡 ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é, emp°¡ Á¾¾÷¿ø µ¥ÀÌÅ͸¦ °¡Áö´Â Å×À̺í·Î Çϸé, ÀÌ À̸§Àº ±× Å×ÀÌºí³»ÀÇ °¢ ÇàÀ» ³ªÅ¸³»´Â º¹ÇÕÇüÀÇ À̸§À̱⵵ ÇÕ´Ï´Ù. ÀÌÇÏ¿¡ ³ªÅ¸³»´Â double_salaryÇÔ¼ö´Â, ÇØ´çÇÏ´Â Á¾¾÷¿øÀÇ ±Þ·á¸¦ ¹è·Î Áõ°¡½Ãŵ´Ï´Ù.

CREATE TABLE emp (
    name        text,
    salary      numeric,
    age         integer,
    cubicle     point
);

CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$
    SELECT $1.salary * 2 AS salary;
$$ LANGUAGE SQL;

SELECT name, double_salary(emp.*) AS dream
    FROM emp
    WHERE emp.cubicle ~= point '(2,1)';

 name | dream
------+-------
 Bill |  8400

$1. salary¶ó´Â ±¸¹®À» »ç¿ëÇØ, ÀÎÀÚÀÇ Çà°ªÀÇ 1 Çʵ带 ¼±ÅÃÇϰí ÀÖ´Â °Í¿¡ ÁÖ¸ñÇØ ÁÖ¼¼¿ä. ¶Ç, *¸¦ »ç¿ëÇÑ SELECT¸í·ÉÀÇ È£Ãâ¿¡¼­´Â, º¹ÇÕÇüÀÇ °ªÀ¸·Î¼­ ÇöÀçÀÇ Å×À̺íÇà Àüü¸¦ ³ªÅ¸³»´Â Å×À̺í¸íÀ» »ç¿ëÇϰí ÀÖÀ½¿¡µµ ÁÖ¸ñÇØ ÁÖ¼¼¿ä. ´Ù¸¥ ¹æ¹ýÀ¸·Î¼­ Å×À̺íÇàÀº ÀÌÇÏ¿Í °°ÀÌ Å×À̺í¸í¸¸À» »ç¿ëÇØ ÂüÁ¶ÇÒ ¼ö ÀÖ½À´Ï´Ù.

SELECT name, double_salary(emp) AS dream
    FROM emp
    WHERE emp.cubicle ~= point '(2,1)';

±×·¯³ª, ÀÌ »ç¿ë ¹æ¹ýÀº, È¥¶õÇϱ⠽±±â ¶§¹®¿¡ ÃßõÇÏÁö ¾Ê½À´Ï´Ù.

±× ÀÚ¸®¿¡¼­ º¹ÇÕÇüÀÇ ÀÎÀÚ°ªÀ» ÀÛ¼ºÇÏ´Â °ÍÀÌ Æí¸®ÇÑ °æ¿ì°¡ ÀÖ½À´Ï´Ù. À̰ÍÀº ROW½Ä¿¡¼­ ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é, ÀÌÇÏ¿Í °°ÀÌ ÇØ ÇÔ¼ö¿¡ °Ç³×ÁÖ´Â µ¥ÀÌÅ͸¦ Á¶Á¤ÇÒ ¼ö ÀÖ½À´Ï´Ù.

SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream
    FROM emp;

º¹ÇÕÇüÀ» µ¹·ÁÁÖ´Â ÇÔ¼ö¸¦ ÀÛ¼ºÇÏ´Â Àϵµ °¡´ÉÇÕ´Ï´Ù. ÀÌÇÏ¿¡ ´ÜÀÏÀÇ empÇàÀ» µ¹·ÁÁÖ´Â ÇÔ¼öÀÇ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION new_emp() RETURNS emp AS $$
    SELECT text 'None' AS name,
        1000.0 AS salary,
        25 AS age,
        point '(2,2)' AS cubicle;
$$ LANGUAGE SQL;

¿©±â¿¡¼­´Â, °¢ ¼Ó¼ºÀ» Á¤¼ö·Î ÁöÁ¤Çϰí ÀÖ½À´Ï´Ù¸¸, ÀÌ Á¤¼ö¸¦ ¾î¶°ÇÑ ¿¬»ê¿¡ ¿Å°Ü³õÀ» ¼öµµ ÀÖ½À´Ï´Ù.

ÇÔ¼ö¸¦ Á¤ÀÇÇϴµ¥ À־, µÎ °¡ÁöÀÇ Áß¿äÇÑ ÁÖÀÇÁ¡À» ÀÌÇÏ¿¡ ³ªÅ¸³À´Ï´Ù.

°°Àº ÇÔ¼ö¸¦ ÀÌÇÏ¿Í °°ÀÌ Á¤ÀÇÇÒ ¼öµµ ÀÖ½À´Ï´Ù.

CREATE FUNCTION new_emp() RETURNS emp AS $$
    SELECT ROW('None', 1000.0, 25, '(2,2)')::emp;
$$ LANGUAGE SQL;

¿©±â¼­, ¿Ã¹Ù¸¥ º¹ÇÕÇüÀÇ ´ÜÀÏÀÇ ¿­À» ´ÜÁö µ¹·ÁÁÖ´Â SELECT¸¦ ±â¼úÇß½À´Ï´Ù. ³Ê¹« ÁÁÀº ÇØ¹ýÀ̶ó°í´Â ¸»ÇÒ ¼ö ¾ø½À´Ï´Ù¸¸, ¿¹¸¦ µé¸é, ÇÊ¿äÇÑ º¹ÇÕ°ªÀ» µ¹·ÁÁÖ´Â ´Ù¸¥ ÇÔ¼ö¸¦ È£ÃâÇØ °á°ú¸¦ °è»êÇØ¾ß ÇÏ´Â °æ¿ì µî, Æí¸®ÇÑ ÇØ¹ýÀÌ µÇ´Â ÀÏÀÌ ÀÖ½À´Ï´Ù.

ÀÌÇÏÀÇ 2°³ÀÇ ¹æ¹ýÀ¸·Î ÀÌ ÇÔ¼ö¸¦ Á÷Á¢ È£ÃâÇÒ ¼ö ÀÖ½À´Ï´Ù.

SELECT new_emp();

         new_emp
--------------------------
 (None,1000.0,25,"(2,2)")

SELECT * FROM new_emp();

 name | salary | age | cubicle
------+--------+-----+---------
 None | 1000.0 |  25 | (2,2)

2¹øÂ°ÀÇ ¹æ¹ý¿¡ ´ëÇØ¼­´Â, Section 33.4.4¿¡¼­ º¸´Ù ÀÚ¼¼ÇÏ°Ô ¼³¸íÇÕ´Ï´Ù.

SQL½Ä¿¡¼­ Çà(º¹ÇÕÇü)À» µ¹·ÁÁÖ´Â ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§¿¡, ±× °á°ú·ÎºÎÅÍ 1°³ÀÇ Çʵå(¼Ó¼º)¸¸À» »ç¿ëÇÏ°í ½ÍÀº °æ¿ì°¡ ÀÖ½À´Ï´Ù. À̰ÍÀº, ÀÌÇÏ¿Í °°Àº ±¸¹®À¸·Î ½Ç½ÃÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

SELECT (new_emp()).name;

 name
------
 None

ÆÄ¼­°¡ È¥¶õÇÏÁö ¾Ê°Ô, °ýÈ£¸¦ Ãß°¡ÇÒ Çʿ䰡 ÀÖ½À´Ï´Ù. °ýÈ£¾øÀÌ ½Ç½ÃÇÏ·Á°í Çϸé, ÀÌÇÏ¿Í °°Àº °á°ú°¡ µË´Ï´Ù.

SELECT new_emp().name;
ERROR:  syntax error at or near "." at character 17
LINE 1: SELECT new_emp().name;
                        ^

¶Ç, ÇÔ¼öÇ¥±â¸¦ »ç¿ëÇØ ¼Ó¼ºÀ» ÃßÃâÇÒ ¼öµµ ÀÖ½À´Ï´Ù. °£´ÜÇÏ°Ô ¼³¸íÇϸé, attribute(table)¿Í table.attribute¶ó´Â Ç¥±â ¹æ¹ý¿¡ »ç¿ëÇÒ ¼ö ÀÖ´Â °ÍÀÔ´Ï´Ù.

SELECT name(new_emp());

 name
------
 None

-- À̰ÍÀº
-- SELECT emp.name AS youngster FROM emp WHERE emp.age < 30;
-- (¿Í)°ú µ¿ÀÏÇÕ´Ï´Ù.

SELECT name(emp) AS youngster FROM emp WHERE age(emp) < 30;

 youngster
-----------
 Sam
 Andy

Tip: ÇÔ¼öÇ¥±â¿Í ¼Ó¼º Ç¥±âÀÇ µ¿µî¼º¿¡ ÀÇÇØ, "°è»ê ó¸®µÈ Çʵå"¸¦ ¸ð¹æÇϱâ À§Çؼ­ º¹ÇÕÇü¿¡ ´ëÇÑ ÇÔ¼ö¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. "computed fields". ¿¹¸¦ µé¸é, »ó±â·Î Á¤ÀÇµÈ double_salary(emp)¸¦ »ç¿ëÇØ, ´ÙÀ½°ú °°ÀÌ ±â¼úÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

SELECT emp.name, emp.double_salary FROM emp;

À̰ÍÀ» ÀÌ¿ëÇÏ´Â ¾îÇø®ÄÉÀ̼ÇÀº, double_salary°¡ ½ÇÁ¦·Î´Â Å×À̺íÀÇ ¿­ÀÌ ¾Æ´Ñ °ÍÀ» Á÷Á¢ ½Å°æ¾µ ÇÊ¿ä´Â ¾ø½À´Ï´Ù (¶Ç, ºäÀÇ °è»ê ó¸®µÈ Çʵ带 ¸ð¹æÇÏ´Â Àϵµ °¡´ÉÇÕ´Ï´Ù).

º¹ÇÕÇüÀ» °á°úÀûÀ¸·Î µ¹·ÁÁÖ´Â ÇÔ¼ö¸¦ »ç¿ëÇÏ´Â ´Ù¸¥ ¹æ¹ýÀº, ±× °á°ú¸¦, ±× ÇàÇüÀ» ÀÔ·ÂÀ¸·Î¼­ ¹Þ¾ÆµéÀÌ´Â ÇÔ¼ö¿¡ °Ç³×ÁÖ´Â, ÀÌÇÏ¿Í °°Àº ¹æ¹ýÀÔ´Ï´Ù.

CREATE FUNCTION getname(emp) RETURNS text AS $$
    SELECT $1.name;
$$ LANGUAGE SQL;

SELECT getname(new_emp());
 getname
---------
 None
(1 row)

º¹ÇÕÇüÀÇ °á°ú¸¦ µ¹·ÁÁÖ´Â ÇÔ¼öÀÇ »ç¿ë ¹æ¹ýÀ¸·Î¼­ ±× ¹Û¿¡µµ, Å×À̺í ÇÔ¼ö·Î¼­ È£ÃâÇÏ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. À̰ÍÀº Section 33.4.4À¸·Î ¼³¸íÇÕ´Ï´Ù.

33.4.3. Ãâ·Â ¸Å°³º¯¼ö¸¦ °¡Áö´Â ÇÔ¼ö

ÇÔ¼öÀÇ °á°úÀÇ ±â¼ú ¹æ¹ý¿¡´Â, ±× ¹Û¿¡µµ Ãâ·Â ¸Å°³º¯¼ö¸¦ »ç¿ëÇØ Á¤ÀÇÇÏ´Â ¹æ¹ýÀÌ ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION add_em (IN x int, IN y int, OUT sum int)
AS 'SELECT $1 + $2'
LANGUAGE SQL;

SELECT add_em(3,7);
 add_em
--------
     10
(1 row)

Section 33.4.1¿¡¼­ °¡¸®Å²add_emÆÇ°ú ±âº»ÀûÀÎ Â÷ÀÌ´Â ¾ø½À´Ï´Ù. º¹¼ö¿­À» µ¹·ÁÁÖ´Â ÇÔ¼ö¸¦ Á¤ÀÇÇÏ´Â °£´ÜÇÑ ¹æ¹ýÀ» Á¦°øÇÏ´Â °ÍÀÌ Ãâ·Â ¸Å°³º¯¼öÀÇ º»·¡ÀÇ °¡Ä¡ÀÔ´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int)
AS 'SELECT $1 + $2, $1 * $2'
LANGUAGE SQL;

 SELECT * FROM sum_n_product(11,42);
 sum | product
-----+---------
  53 |     462
(1 row)

À̰ÍÀº ±âº»ÀûÀ¸·Î, ÇÔ¼ö °á°ú¿ëÀÇ À͸íÀÇ º¹ÇÕÇüÀÇ ÀÛ¼ºÀ» ½Ç½ÃÇÕ´Ï´Ù. À§ÀÇ ¿¹¿¡¼­´Â,

CREATE TYPE sum_prod AS (sum int, product int);

CREATE FUNCTION sum_n_product (int, int) RETURNS sum_prod
AS 'SELECT $1 + $2, $1 * $2'
LANGUAGE SQL;

±×·¯³ª, µ¶¸³ÇÑ º¹ÇÕÇü Á¤ÀÇ¿¡ °ñÄ¡¸¦ ½â´Â ÀÏÀÌ ¾ø¾îÁ®, Æí¸®ÇÏ´Ù¶ó°í ¸»ÇÒ ¼ö ÀÖ½À´Ï´Ù.

SQL·ÎºÎÅÍ ÇÔ¼ö¸¦ È£ÃâÇÒ ¶§, Ãâ·Â ¸Å°³º¯¼ö°¡ È£ÃâÇØ ¿·ÀÇ ÀÎÀÚ ¸®½ºÆ®¿¡ Æ÷ÇÔµÇÁö ¾Ê´Â °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä. PostgreSQL°¡, ÀÔ·Â ¸Å°³º¯¼ö¸¸ÀÌ ÇÔ¼öÀÇ È£Ãâ ¼­¸íÀ» Á¤ÀÇÇϱ⠶§¹®¿¡ÀÔ´Ï´Ù. À̰ÍÀº ¶Ç, ÇÔ¼ö¸¦ »èÁ¦Çϱâ À§Çؼ­ ÇÔ¼ö¸¦ ÂüÁ¶ÇÏ´Â °æ¿ì, ÀÔ·Â ¸Å°³º¯¼ö¸¸ÀÌ °í·ÁµÇ´Â °ÍÀ» ÀǹÌÇϰí ÀÖ½À´Ï´Ù. À§ÀÇ ÇÔ¼ö´Â, ´ÙÀ½ÀÇ ¸î°³ÀÇ ¹æ¹ýÀ¸·Î »èÁ¦ÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù.

DROP FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int);
DROP FUNCTION sum_n_product (int, int);

¸Å°³º¯¼ö¿¡´Â, IN (±âº»°ª), OUT ¶Ç´Â INOUT¶ó´Â Ç¥½Ã¸¦ ºÎ¿©ÇÒ ¼ö ÀÖ½À´Ï´Ù. INOUT¸Å°³º¯¼ö´Â, ÀÔ·Â ¸Å°³º¯¼ö(È£Ãâ Àμö ¸®½ºÆ®ÀÇ ÀϺÎ)¿Í Ãâ·Â ¸Å°³º¯¼ö(°á°úÀÇ ·¹ÄÚµåÇüÀÇ ÀϺκÐ)ÀÇ ¾çÂÊ ¸ðµÎ¸¦ Á¦°øÇÕ´Ï´Ù.

33.4.4. Å×ÀÌºí ¼Ò½º·Î¼­ÀÇ SQLÇÔ¼ö

¸ðµç SQL ÇÔ¼ö´Â Äõ¸®ÀÇ FROM±¸·Î »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù¸¸, º¹ÇÕÇüÀ» µ¹·ÁÁÖ´Â ÇÔ¼ö¿¡ ƯÈ÷ Æí¸®ÇÕ´Ï´Ù. ÇÔ¼ö°¡ ±âº»ÇüÀ» µ¹·ÁÁÖµµ·Ï Á¤Àǵǰí ÀÖ´Â °æ¿ì, Å×À̺í ÇÔ¼ö´Â 1¿­·ÎºÎÅÍ µÇ´Â Å×À̺íÀ» ÀÛ¼ºÇÕ´Ï´Ù. ÇÔ¼ö°¡ º¹ÇÕÇüÀ» µ¹·ÁÁÖµµ·Ï Á¤Àǵǰí ÀÖ´Â °æ¿ì, Å×À̺í ÇÔ¼ö´Â º¹ÇÕÇüÀÇ ¿­ÀÇ °¢°¢ ´ëÇØ 1°³ÀÇ ¿­À» ÀÛ¼ºÇÕ´Ï´Ù.

ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe');
INSERT INTO foo VALUES (1, 2, 'Ed');
INSERT INTO foo VALUES (2, 1, 'Mary');

CREATE FUNCTION getfoo(int) RETURNS foo AS $$
    SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;

SELECT *, upper(fooname) FROM getfoo(1) AS t1;

 fooid | foosubid | fooname | upper
-------+----------+---------+-------
     1 |        1 | Joe     | JOE
(1 row)

¿¹¿¡¼­ º¸¿©ÁÖ´Â ´ë·Î, ÇÔ¼öÀÇ °á°úÀÇ ¿­À» º¸ÅëÀÇ Å×À̺íÀÇ ¿­°ú °°ÀÌ Ãë±ÞÇÒ ¼ö ÀÖ½À´Ï´Ù.

ÀÌ ÇÔ¼öÀÇ °á°ú ¾òÀ» ¼ö ÀÖ´ø °ÍÀº 1Çà»ÓÀÎ °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä. À̰ÍÀº SETOF¸¦ ÁöÁ¤ÇÏÁö ¾Ê¾Ò±â ¶§¹®ÀÔ´Ï´Ù. À̰Ϳ¡ ´ëÇØ¼­´Â ´ÙÀ½ ¼½¼Ç¿¡¼­ ¼³¸íÇÕ´Ï´Ù.

33.4.5. ÁýÇÕÀ» µ¹·ÁÁÖ´ÂSQLÇÔ¼ö

SQL ÇÔ¼ö°¡ SETOF sometype ¸¦ µ¹·ÁÁÖµµ·Ï ¼±¾ðµÇ°í ÀÖ´Â °æ¿ì, ÇÔ¼öÀÇ ¸¶Áö¸· SELECTÄõ¸®´Â ³¡±îÁö ½ÇÇàµÇ¾î °¢ Ãâ·ÂÇàÀº °á°ú ÁýÇÕÀÇ ¿ä¼Ò·Î¼­ µ¹·ÁÁÖ¾îÁý´Ï´Ù.

ÀÌ ±â´ÉÀº Åë»ó, ÇÔ¼ö¸¦ FROM±¸³»¿¡¼­ È£ÃâÇÒ ¶§¿¡ »ç¿ëµË´Ï´Ù. ÀÌ °æ¿ì, ÇÔ¼ö¿¡ ÀÇÇØ µ¹·ÁÁÖ¾îÁö´Â °¢ ÇàÀº, Äõ¸®¿¡ ÀÇÇØ º¸ÀÌ´Â Å×À̺íÀÇ ÇàÀÌ µË´Ï´Ù. ¿¹¸¦ µé¸é, Å×À̺ífooÀÇ ³»¿ëÀÌ »ó±â¿Í °°À¸¸é ÀÌÇÏ¿Í °°ÀÌ µË´Ï´Ù.

CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
    SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;

SELECT * FROM getfoo(1) AS t1;

ÀÌ Ãâ·ÂÀº ÀÌÇÏ¿Í °°½À´Ï´Ù.

 fooid | foosubid | fooname
-------+----------+---------
     1 |        1 | Joe
     1 |        2 | Ed
(2 rows)

ÇöÀç, ÁýÇÕÀ» µ¹·ÁÁÖ´Â ÇÔ¼ö´Â Äõ¸®ÀÇ ¼±Åà ¸®½ºÆ®³»¿¡¼­µµ È£ÃâÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. Äõ¸® Àڽſ¡ ÀÇÇØ »ý¼ºÇÏ´Â °¢ Çà¿¡ ´ëÇØ, ÁýÇÕÀ» µ¹·ÁÁÖ´Â ÇÔ¼ö°¡ ºÒ·Á °¡ ÇÔ¼öÀÇ °á°ú ÁýÇÕÀÇ °¢ ¿ä¼Ò¿¡ ´ëÇØ¼­ Ãâ·ÂÇàÀÌ »ý¼ºµË´Ï´Ù. ´Ù¸¸, ÀÌ ±â´ÉÀº ÇöÀç´Â Ãßõ µÇÁö ¾Ê°í, ÇâÈÄÀÇ ¸±¸®½º¿¡¼­´Â »èÁ¦µÉ °¡´É¼ºÀÌ ÀÖ½À´Ï´Ù. ÀÌÇÏ´Â, ¼±Åà ¸®½ºÆ®·ÎºÎÅÍ ÁýÇÕÀ» µ¹·ÁÁÖ´Â ÇÔ¼öÀÇ ¿¹ÀÔ´Ï´Ù.

CREATE FUNCTION listchildren(text) RETURNS SETOF text AS $$
    SELECT name FROM nodes WHERE parent = $1
$$ LANGUAGE SQL;

SELECT * FROM nodes;
   name    | parent
-----------+--------
 Top       |
 Child1    | Top
 Child2    | Top
 Child3    | Top
 SubChild1 | Child1
 SubChild2 | Child1
(6 rows)

SELECT listchildren('Top');
 listchildren
--------------
 Child1
 Child2
 Child3
(3 rows)

SELECT name, listchildren(name) FROM nodes;
  name  | listchildren
--------+--------------
 Top    | Child1
 Top    | Child2
 Top    | Child3
 Child1 | SubChild1
 Child1 | SubChild2
(5 rows)

¸¶Áö¸· SELECT¿¡ ´ëÇØ, Child2¿ÍChild3µîÀÌ Ãâ·ÂÇà¿¡ Ç¥½ÃµÇ¾î ÀÖÁö ¾ÊÀº °Í¿¡ ÁÖÀÇÇØ ÁÖ¼¼¿ä. À̰ÍÀº, listchildren°¡ ÀÌ ÀԷ¿¡ ´ëÇØ¼­ ºó°ªÀÇ ÁýÇÕÀ» µ¹·ÁÁÖ¾î, Ãâ·ÂÇàÀÌ »ý¼ºµÇÁö ¾Ê±â ¶§¹®ÀÔ´Ï´Ù.

33.4.6. ´ÙÇüSQLÇÔ¼ö

SQLÇÔ¼ö´Â, ´ÙÇü anyelement, anyarray, anynonarray ¹× anyenum¸¦ ¹Þ¾Æµé¿© µ¹·ÁÁÖµµ·Ï ¼±¾ðÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ´ÙÇü ÇÔ¼öÀÇ »ó¼¼ ¼³¸í¿¡ ´ëÇØ¼­´Â Section 33.2.5À» ÂüÁ¶ÇØ ÁÖ¼¼¿ä. ÀÌÇÏÀÇ make_array´ÙÇü ÇÔ¼ö´Â, ÀÓÀÇÀÇ 2°³ÀÇ µ¥ÀÌÅÍÇü ¿ä¼Ò·ÎºÎÅÍ ¹è¿­À» ÀÛ¼ºÇÕ´Ï´Ù.

CREATE FUNCTION make_array(anyelement, anyelement) RETURNS anyarray AS $$
    SELECT ARRAY[$1, $2];
$$ LANGUAGE SQL;

SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray;
 intarray | textarray
----------+-----------
 {1,2}    | {a,b}
(1 row)

'a'::text¶ó°í ÇÏ´Â ÇüÅ ij½ºÆ®¸¦ »ç¿ëÇØ, ÀÎÀÚ°¡ textÇüÀÎ °ÍÀ» ÁöÁ¤Çϰí ÀÖ´Â °Í¿¡ ÁÖ¸ñÇØ ÁÖ¼¼¿ä. À̰ÍÀº ÀÎÀÚ°¡ ´Ü¼øÇÑ ¹®ÀÚ¿­ ¸®ÅÍ·²ÀÎ °æ¿ì¿¡ ÇÊ¿äÇÕ´Ï´Ù. ±×·¸Áö ¾ÊÀ¸¸é, unknownÇüÀ¸·Î¼­ ´Ù·ç¾îÁö±â ¶§¹®¿¡, ¹«È¿ÀÎ unknownÀÇ ¹è¿­À» µ¹·ÁÁÖ·Á°í ³¡³À´Ï´Ù. ÇüÅ ij½ºÆ®°¡ ¾øÀ¸¸é ÀÌÇÏ¿Í °°Àº ¿¡·¯°¡ ¹ß»ýÇÕ´Ï´Ù.

ERROR:  could not determine "anyarray"/"anyelement" type because input has type "unknown"

°íÁ¤ÀÇ ¹Ýȯ°ªÇüÀ¸·Î ´ÙÇü Àμö¸¦ °¡Áö´Â °ÍÀº Çã¿ëµË´Ï´Ù¸¸, ¿ªÀº Çã¿ëµÇÁö ¾Ê½À´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$
    SELECT $1 > $2;
$$ LANGUAGE SQL;

SELECT is_greater(1, 2);
 is_greater
------------
 f
(1 row)

CREATE FUNCTION invalid_func() RETURNS anyelement AS $$
    SELECT 1;
$$ LANGUAGE SQL;
ERROR:  cannot determine result data type
DETAIL:  A function returning "anyarray" or "anyelement" must have at least one argument of either type.

Ãâ·Â ÀÎÀÚ¸¦ °¡Áö´Â ÇÔ¼ö¿¡¼­µµ ´ÙÇü¼ºÀ» »ç¿ëÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ÀÌÇÏ¿¡ ¿¹¸¦ ³ªÅ¸³À´Ï´Ù.

CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray)
AS 'select $1, array[$1,$1]' LANGUAGE sql;

SELECT * FROM dup(22);
 f2 |   f3
----+---------
 22 | {22,22}
(1 row)