ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.
proc <a href="/modules/moniwiki/wiki.php/manSearch?google=none&name=ÇÁ·Î±×·¡¹Ö">ÇÁ·Î±×·¡¹Ö</a>(2)

1절. ¼Ò°³

À̹øÀå¿¡¼­´Â Proc ÇÁ·Î±×·¡¹ÖÀ» Á»´õ ±íÀÌ ÀÖ°Ô ´Ù·ç¾î º¸µµ·Ï ÇϰڴÙ. Proc ÇÁ·Î±×·¡¹Ö ȯ°æÀº ÀÌ¹Ì ´Ù °®Ãß¾îÁ® ÀÖÀ¸¸ç, proc °¡ ¹«¾ùÀÎÁöµµ °³³äÀ» Àâ°í ÀÖ´Ù°í °¡Á¤ÇÏ°í °­Á¸¦ ÁøÇàÇÒ °ÍÀÌ´Ù. sql ¿ª½Ã ±âº»ÀûÀ¸·Î »ç¿ëÇÒÁÙ ¾Æ´Â°É·Î °¡Á¤ÇϰڴÙ.

¸¸¾à À§ÀÇ ³»¿ëµéÀÌ ÁغñµÇ¾î ÀÖÁö ¸øÇÏ´Ù¸é proc ÇÁ·Î±×·¡¹Ö(1) °ú ¿À¶óŬ 817 ¼³Ä¡Çϱ⠹®¼­¸¦ ¸ÕÀú ÀÐ¾î º¸±â ¹Ù¶õ´Ù.

À̿ܿ¡µµ Proc ¿Í Á÷Á¢ÀûÀÎ °ü·ÃÀº ¾øÁö¸¸ termios ¸¦ ÀÌ¿ëÇÑ Å͹̳ΠÁ¦¾î¿Í ANSI ¸¦ ÀÌ¿ëÇÑ È­¸éÁ¶Á¤¿¡ ´ëÇÑ ³»¿ëµµ Äڵ带 ÅëÇØ¼­ ¾à°£ ´Ù·ç°Ô µÉ°ÍÀÌ´Ù. termios ´Â Á¶¸¸°£ ÀڷḦ ¸¸µé¾î¼­ ¿Ã¸± »ý°¢ÀÌ´Ï, ÀÌ ¹®¼­¿¡¼­´Â ±×³É ÀÌ·¯ÇÑ µµ±¸¸¦ ÀÌ¿ëÇØ¼­ Å͹̳ΠÁ¦¾î°¡ °¡´ÉÇϱ¸³ª.. ÇÏ´Â Á¤µµ·Î¸¸ ¾Ë¾ÆµÎ±æ ¹Ù¶õ´Ù.


2절. proc ÇÁ·Î±×·¡¹ÖÀÇ ±âº»

2.1절. proc ¹®ÀÇ ±¸Á¶

±âº»ÀûÀ¸·Î proc ´Â C ÄÚµå¿Í ÇÔ²² ¾²À̵µ·Ï µÇ¾î ÀÖ´Ù. À̸¦Å׸é C ÄÚµå¾È¿¡ SQL ¹®À» Æ÷ÇÔ(embedded) ½ÃŰ´Â ÀÏÀ» ÇÑ´Ù. ±×·³À¸·Î proc °¡ ±¸Á¶ÀûÀ¸·Î °¡Á®¾ßµÉ °¡Àå Áß¿äÇÑ Æ¯Â¡Àº ¹Ù·Î (oracle)sql °ú C ÇÁ·Î±×·¥°úÀÇ µ¥ÀÌŸ ±³È¯ÀÌ µÉ°ÍÀÌ´Ù.

proc ´Â C ¿ÍÀÇ µ¥ÀÌŸ ±³È¯À» Áö¿øÇϱâ À§Çؼ­ 4°¡Áö Å« ±¸Á¶·Î ³ª´¶´Ù. Çϳª´Â Executable ¿µ¿ªÀ̸ç, ´Ù¸¥ Çϳª´Â Declarative ¿µ¿ªÀÌ´Ù. ¶ÇÇÑ PL/SQL ºí·°À» Ãß°¡ ½Ãų¼ö ÀÖÀ¸¸ç, SQL ¸í·ÉÀÇ ½ÇÇà »óŸ¦ ÃøÁ¤Çϱâ À§ÇÔ Indicator Variables µîÀ» »ç¿ëÇÒ¼ö ÀÖ´Ù.


2.1.1절. Executable ¿µ¿ª

Executable À̶ó´Â ¾î°¨¿¡¼­ ¾Ë¼ö ÀÖµíÀÌ, Executable Àº SQLLIB ¸¦ ½ÇÇà½Ã°£¿¡ È£ÃâÇϱâ À§Çؼ­ »ç¿ëµÇ´Â ¿µ¿ªÀÌ´Ù. SQLLIB ¸¦ È£ÃâÇÔÀ¸·Î½á C(ȤÀº C++)·Î µÈ Äڵ忡¼­ ¿À¶óŬ SQL À» ½ÇÇàÇÏ°í ¶§¿¡ µû¶ó¼­´Â SQL ¹®¿¡ C ¿¡¼­ ¼±¾ðÇÑ °ªÀ» ÀÔ·ÂÇϰųª ȤÀº SQL Äõ¸® °á°ú¸¦ C ¿¡¼­ ¼±¾ðÇÑ º¯¼ö¿¡ Ãâ·ÂÇÒ¼ö ÀÖ°Ô µÈ´Ù.

Executable ¿µ¿ªÀº ¿À¶óŬ ¿¡¼­ µ¥ÀÌŸº£À̽º °ü¸®¸¦ À§Çؼ­ »ç¿ëÇϴ ǥÁØ SQL °ú È®Àå(¿À¶óŬ¿¡¼­ Ãß°¡ÇÑ) SQL ¹®À» ½ÇÇàÇÑ´Ù. Áï Å×À̺íÀ» »ý¼ºÇϰųª CREATE, Áö¿ì°í DROP, ±ÇÇÑ ¼³Á¤À» Çϰí GRANT, °ªÀ» °¡Á®¿À°Å³ª SELECT, °ªÀ» Áö¿ì´Â DELETE µîÀÇ ÀÏÀ» ó¸®ÇÏ°Ô µÈ´Ù. SQL ¹®À» C Äڵ忡 embeded ½Ã۱â À§ÇÑ ¿µ¿ªÀ̶ó°í »ý°¢ÇÏ¸é µÈ´Ù.

´ÙÀ½Àº Executable ¿µ¿ª¿¡¼­ ´Ù·ê¼ö ÀÖ´Â SQL °ü·Ã ½ÇÇ๮ÀÌ´Ù. ÀÌ ¹®¼­´Â ORACLE SQL ÀÚü¿¡ ´ëÇÑ °­Àǹ®¼­´Â ¾Æ´ÔÀ¸·Î ÀÌ·¯ÇÑ ÀϵéÀ» ÇÒ¼ö ÀÖ´Ù¶ó´Â Á¤µµ·Î ¿­°Å¸¸ Çϵµ·Ï ÇϰڴÙ. Á¶±ÝÀÌ¶óµµ SQL À» ´Ù·ç¾î º¸¾Ò´Ù¸é ´ëºÎºÐ ¹«½¼ÀÏÀ» ÇÏ´Â ¸í·É¾îÀÎÁö ÀÌÇØµÉ°ÍÀÌ´Ù.

CLOSE, CONNECT, CREATE, DROP, FREE, GRANT, AOAUDIT, RENAME, TRUNCATE, 
DELETE, EXPLAIN PLAN, FETCH, INSERT, LOCK TABLE, OPEN, SELECT, UPDATE, 
COMMIT(Æ®·£Àè¼Ç°ü¸®), ROLLBACK, SAVEPOINT, SET TRANSACTION, 
DESCRIBE(dynamic sql ¿ë), EXECUTE, PREPARE, ALTER SESSION(¼¼¼Ç Á¦¾î¿ë)
				
À§ÀÇ ¸í·É¾îµéÀº ´Ù½Ã Interactive ÇѰͰú ±×·¸Áö ¾ÊÀº °Í (no Interactive)À¸·Î ³ª´¶´Ù. ÀÎÅÍ¿¢Æ¼ºê¶õ SQL¹® ½ÇÇà°á°ú¿Í CÇÁ·Î±×·¥°£ÀÇ µ¥ÀÌŸ ±³È¯ÀÌ ÀÖ´Â °ÍÀ» ¸»Çϸç, no ÀÎÅÍ¿¢Æ¼ºê¶õ SQL ¹®¸¸ ´Üµ¶À¸·Î ½ÇÇàµÇ¸ç C ÇÁ·Î±×·¥°úÀÇ µ¥ÀÌŸ ±³È¯ÀÌ ¾ø´Â°É ¸»ÇÑ´Ù. no Interactive ÇÑ ¹®À¸·Î´Â CONNECT, FETCH, OPEN, DESCRIBE, EXECUTE, PREPARE °¡ ÀÖ´Ù. - ³ª¸ÓÁö´Â ¸ðµÎ CÄÚµå¿Í ÀÎÅÍ¿¢Æ¼ºê ÇÏ°Ô ÀÛ¿ë(»óÈ£ÀÛ¿ë)ÇÑ´Ù - º¹ÀâÇÏ°Ô »ý°¢ÇÒ ÇÊ¿ä ¾øÀÌ ±×³É »ó½ÄÀûÀ¸·Î »ý°¢ÇÏ¸é µÈ´Ù. ¿À¶óŬ°ú ¿¬°áÇϰí, DB ¸¦ OPEN Çϴµ¥´Â CÄÚµå¿Í ¾ê±âÇÒ Çʿ䰡 ÀüÇô ¾øÀ» °ÍÀÌ´Ù. ±×³É ¿¬°áÇÏ°í ¿ÀÇÂÇÏ¸é µÇ±â ¶§¹®ÀÌ´Ù. ¹Ý¸é SELECT ÀÇ °æ¿ì ¿À¶óŬ¿¡¼­ SELECT ÇÑ °á°ú¸¦ C ÇÁ·Î±×·¥¿¡ µÇµ¹·ÁÁÖ¾î¾ß ÇÔÀ¸·Î interactive ÇÏ°Ô ÀÛ¿ëÇÒ Çʿ䰡 ÀÖ´Ù.

interactive ÇÏ°Ô »ç¿ëÇϱâ À§Çؼ­º¸Åë ":" À» »ç¿ëÇÏ°Ô µÈ´Ù. ¿¹¸¦µé¾î¼­ ¿À¶óŬ DB ¿¡¼­ ¼¿·ºÆ®ÇÑ °á°ú¸¦ C ÇÁ·Î±×·¥ÀÇ º¯¼ö¿¡ ÀúÀåÇÏ±æ ¿øÇÑ´Ù¸é ¾Æ·¡¿Í °°Àº ¹æ¹ýÀ¸·Î »ç¿ëÇÏ¸é µÈ´Ù.

char zipcode[12];
EXEC SQL SELECT zipcode 
         INTO : zipcode[12] 
         FROM zipcode where zipcode_no = "500-180";
				
C ÇÁ·Î±×·¥¿¡¼­ ¾Ë¾Æ¿Í¾ß µÉ °ªÀº SELECT ·Î °¡Á®¿À°Ô µÇ´Â zipcode °ªÀÌ´Ù. À̰ÍÀ» C ÇÁ·Î±×·¥¿¡¼­ ¼±¾ðÇÑ zipcode ·Î ³Ñ°ÜÁÖ±â À§Çؼ­(INTO) ":" ¸¦ »ç¿ëÇϰí ÀÖÀ½À» ¾Ë¼ö ÀÖ´Ù.


2.1.2절. DECLARATIVE Áö¿ø

±âº»ÀûÀ¸·Î C ÀÇ ÀÚ·áÇü°ú SQL ¿¡¼­ ´Ù·ç´Â ÀÚ·áÇüÀº ¼­·Î ȣȯµÇÁö ¾Ê´Â´Ù.

±×·³À¸·Î À̵éÀÇ È£È¯À» º¸ÀåÇØÁÙ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ÇØ¼­ proc ´Â º°µµÀÇ ¼±¾ð(Declarative) ¿µ¿ªÀ» µÎ¾î¼­, ¼±¾ðÀ» ÇÏ°Ô Çϰí proc ÇÁ¸®ÄÄÆÄÀÏ·¯¸¦ µ¹·Á¼­ ³ªÁß¿¡ C ÄÚµå¿Í ȣȯ°¡´É Çϵµ·Ï º¯È¯ÇÏ´Â Á¤Ã¥À» »ç¿ëÇϰí ÀÖ´Ù.


2.1.3절. Embedded PL/SQL Blocks

proc ´Â PL/SQL ºí·°À» C ÄÚµå»ó¿¡¼­ »ç¿ëÇÒ¼ö ÀÖµµ·Ï µµ¿ÍÁØ´Ù. PL/SQL ºí·°À» Ãß°¡Çϱâ À§Çؼ­ ´ÜÁö EXEC SQL EXECUTE ¿Í END-EXEC ¸¸À» »ç¿ëÇÏ¸é µÈ´Ù.

PL/SQL Àº ±âº»ÀûÀ¸·Î ¸ðµç SQL µ¥ÀÌŸ¸¦ Á¦¾îÇÒ¼ö ÀÖµµ·Ï Áö¿øÇϸç, ¾Æ¿ï·¯ Æ®·£Àè¼Ç±îÁöµµ ÇØ°áÇØÁØ´Ù. ±×·³À¸·Î ÈξÀ ¾ÈÁ¤¼ºÀÖ°í, À¯Áö °ü¸® ÆíÇÑ Äڵ带 ¸¸µé¼ö ÀÖµµ·Ï µµ¿Í ÁØ´Ù.


2.1.4절. host º¯¼ö¿Í indicator º¯¼ö

Host º¯¼ö´Â ¿À¶óŬ°ú ¾îÇø®ÄÉÀ̼Ç(C/C++ ·ÎµÈ) »çÀÌÀÇ Åë½Å(µ¥ÀÌŸ ±³È¯)À» À§Çؼ­ »ç¿ëµÈ´Ù. ÀÌµé º¯¼ö´Â C ÄÚµå »ó¿¡¼­ »ý¼ºµÇ¸ç, ¼±¾ðµÈ º¯¼ö´Â C ¿Í °øÀ¯ÇÒ¼ö ÀÖ°Ô µÈ´Ù.

host º¯¼ö´Â Å©°Ô input host º¯¼ö¿Í output host º¯¼ö°¡ Àִµ¥, input host º¯¼ö´Â ÇÁ·Î±×·¥ µ¥ÀÌŸ¸¦ Oracle ¿¡ ³Ñ°ÜÁÖ±â À§Çؼ­ »ç¿ëµÇ¸ç, output host º¯¼ö´Â ¿À¶óŬÀÇ µ¥ÀÌŸ(Äõ¸® °á°úµî)À» ÇÁ·Î±×·¥¿¡°Ô ³Ñ°ÜÁÖ±â À§Çؼ­ »ç¿ëÇÑ´Ù. ÀÌ·¯ÇÑ È£½ºÆ®º¯¼öÀÇ »ç¿ëÀº ¿À¶óŬ¹®Àå¿¡ ":" ¸¦ ÀÌ¿ëÇÔÀ¸·Î½á »ç¿ë°¡´ÉÇÏ°Ô µÈ´Ù.

¶ÇÇÑ indicator º¯¼ö¸¦ »ç¿ëÇÒ¼öµµ Àִµ¥, indicator ¶õ ¶æ¿¡¼­ »ý°¢ÇÒ¼ö ÀÖµíÀÌ ¿À¶óŬ¹®ÀÇ ½ÇÇà°á°ú¸¦ ÃøÁ¤Çϱâ À§ÇÑ ¿ëµµ·Î »ç¿ëÇÑ´Ù. À̸¦Å׸é CONNECT ¸¦ ÅëÇØ¼­ ORACLE DB ¼­¹ö·Î ¿¬°áÀ» ½ÃµµÇßÀ»¶§ÀÇ ¼º°øÈ¤Àº ½ÇÆÐ¿¡ ´ëÇÑ ¸®ÅϰªÀ̶ó°í º¸¸é µÉ°ÍÀÌ´Ù. Á»´õ ±â¼úÀûÀ¸·Î ¸»ÇÏÀÚ¸é indicator º¯¼ö´Â host º¯¼öÀÇ »óŸ¦ ÃøÁ¤Çϱâ À§ÇÑ ¿ëµµ·Î »ó¿äµÈ´Ù.


2.1.5절. Cursor °ú Fetch ÀÇ Áö¿ø

fetch ¶ó¸é ƯÈ÷ php+mysql À» ÀÌ¿ëÇÑ À¥ÇÃ¹Ö ÀÛ¾÷À» Çϸ鼭 ¸¹ÀÌ ´Ù·ç¾î º¸¾ÒÀ»°ÍÀÌ´Ù. proc ¿¡¼­´Â Äõ¸®°á°ú¹°(¸®½ºÆ®) ÀÇ °ü¸®¸¦ À§Çؼ­ Cursor °ú Fetch ¸¦ Áö¿øÇÑ´Ù.


2.2절. ¿À¶óŬÀÇ µ¥ÀÌŸ ŸÀÔ

proc ÇÁ·Î±×·¡¹ÖÀÇ ÀϹÝÀûÀÎ ¹æ¹ýÀº C ÇÁ·Î±×·¥¿¡¼­ input host º¯¼ö¸¦ ÅëÇØ¼­ ORACLE Ãø¿¡ µ¥ÀÌŸ¸¦ ¿äûÇϸé, ORACLE µ¥ÀÌŸº£À̽º´Â output host º¯¼ö¸¦ ÅëÇØ¼­ C ÇÁ·Î±×·¥¿¡ µ¥ÀÌŸ¸¦ µÇµ¹·Á ÁÖ´Â ¹æ½ÄÀ» »ç¿ëÇÑ´Ù. ±×·¯¹Ç·Î ¿À¶óŬÀº ¹Ýµå½Ã C ÇÁ·Î±×·¥°úÀÇ Åë½Å¿¡ »ç¿ëµÇ´Â µ¥ÀÌŸÀÇ Å¸ÀÔ¿¡ ´ëÇØ¼­ ¾Ë°í ÀÖ¾î¾ß¸¸ ÇÑ´Ù.

¿À¶óŬÀº interanl °ú external 2°¡ÁöÀÇ µ¥ÀÌŸ ŸÀÔÀ» ÀνÄÇÑ´Ù. interanl µ¥ÀÌŸ ŸÀÔÀº ¿À¶óŬ µ¥ÀÌŸº£À̽º¿¡¼­ °¢°¢ÀÇ Ä®·³ÀÇ µ¥ÀÌŸ ŸÀÔÀ» ÁöÁ¤Çϱâ À§Çؼ­ »ç¿ëÇÏ´Â µ¥ÀÌŸ ŸÀÔÀÌ´Ù.

external µ¥ÀÌŸ ŸÀÔÀº host º¯¼ö¸¦ ÅëÇØ¼­ ÀúÀåµÉ µ¥ÀÌŸÀÇ Å¸ÀÔÀ» ¸»ÇÑ´Ù. ¸¸¾à C ÇÁ·Î±×·¥¿¡¼­ input host º¯¼ö¸¦ ÅëÇØ¼­ ¿À¶óŬ¿¡ µ¥ÀÌŸ¸¦ Àü´ÞÇß´Ù¸é, ¿À¶óŬÀº ÀÌ º¯¼ö¸¦ external µ¥ÀÌŸ·Î °£ÁÖÇϰí À̰ÍÀ» ¿À¶óŬÀÚ½ÅÀÌ »ç¿ëÇÏ´Â internal µ¥ÀÌŸ ŸÀÔ°ú ÀÏÄ¡½ÃÄѼ­ ÀÛ¾÷À» ÇÏ°Ô µÈ´Ù. ¸¶Âù°¡Áö·Î ÀÛ¾îÀ» ¸¶Ä¡°í µ¥ÀÌŸ¸¦ µÇµ¹·Á ÁÙ¶§µµ internal µ¥ÀÌŸ ŸÀÔÀ» external µ¥ÀÌŸ ŸÀÔÀ¸·Î º¯°æ½ÃŲÈÄ output host º¯¼ö¿¡ ÀúÀåÇØ¼­ µÇµ¹·Á ÁÖ°Ô µÈ´Ù. ÀÌ·¯ÇÑ º¹ÀâÇÑ µ¥ÀÌŸ º¯È¯ÀÛ¾÷ÀÌ ÀϾ´Â ÀÌÀ¯´Â C ÇÁ·Î±×·¥¿¡¼­ »ç¿ëÇÏ´Â µ¥ÀÌŸ ŸÀÔ°ú ¿À¶óŬ¿¡¼­ »ç¿ëÇÏ´Â µ¥ÀÌŸ ŸÀÔÀÌ ±Ùº»ÀûÀ¸·Î ¼­·Î ´Ù¸£±â ¶§¹®ÀÌ´Ù. ³»ºÎÀûÀ¸·Î º¸ÀÚ¸é proc ´Â ÀÌ·¯ÇÑ µ¥ÀÌŸ ŸÀÔÀÇ ÀÏÄ¡¸¦ À§Çؼ­ void * Çüº¯È¯À» ÀÌ¿ëÇÑ´Ù.

proc ´Â È£½ºÆ® º¯¼ö·Î ¹è¿­À» »ç¿ëÇÒ¼ö ÀÖµµ·Ï Áö¿øÇϸç, ¸¶Âù°¡Áö·Î ±¸Á¶Ã¼µµ Áö¿øÇÑ´Ù. ÀÌ·¯ÇÑ ¹è¿­/±¸Á¶Ã¼ °¡ »ç¿ëµÉ¼ö ÀÖ´Â °÷Àº SQL ¹®À» »ç¿ëÇÒ°æ¿ìÀÌ´Ù. Áï SELECT, FETCH, DELETE, INSERT, UPDATE µî¿¡ »ç¿ëÇÒ¼ö ÀÖ´Ù.


2.3절. Transaction

¿À¶óŬ¿¡¼­ Transaction Àº ¸Å¿ì Áß¿äÇÑ ¿ä¼ÒÀÌ´Ù. Transaction Àº À̸¦Å×¸é µ¥ÀÌŸÀÇ ¹«°á¼ºÀ» °ËÁõ½ÃÄÑÁÖ±â À§Çؼ­ SQL »óŸ¦ ³í¸®ÀûÀÎ ÇϳªÀÇ »óÅ·Π°ü¸®ÇÏ´Â °ÍÀ̶ó°í º¼¼ö ÀÖ´Ù.

oracle Àº transaction À» À¯ÁöÇϱâ À§Çؼ­ COMMIT ¿Í ROLLBACK ¸¦ ÀÌ¿ëÇϴµ¥, proc ¿¡¼­µµ ¸¶Âù°¡Áö·Î COMMIT, ROLLBACK ¸¦ ±×´ë·Î ÀÌ¿ëÇØ¼­ Æ®·£Àè¼ÇÀ» ó¸®ÇÒ¼ö ÀÖµµ·Ï µµ¿ÍÁØ´Ù. ÀÌ·¯ÇÑ ÀÛ¾÷Àº ƯÈ÷ PL/SQL ±¸¹®À» ÀÌ¿ëÇÔÀ¸·Î½á C ÄÚµå»ó¿¡ ½±°Ô ÀÓº£µðµå ½Ãų¼ö ÀÖ´Ù. ¾Æ·¡´Â Executable SQL¹®À» ÀÌ¿ëÇØ¼­ ¾î¶»°Ô Æ®·£Àè¼Ç󸮸¦ ÇÒ¼ö ÀÖ´ÂÁö¸¦ º­¿©ÁØ´Ù.

...
EXEC SQL
   UPDATE zipcode 
   SET dong =: mdong
   WHERE bunji =: mbungi

if (sqlca.sqlcode == 0)
    EXEC SQL COMMIT WORK
else 
    EXEC SQL ROLLBACK WORK;
...
			


2.4절. Error Á¦¾î

Á¦´ë·ÎµÈ ÇÁ·Î±×·¥Àº Á¦´ë·ÎµÈ ¿¡·¯Ã³¸® ·çƾÀ» °¡Áø´Ù. proc ´Â WHENEVER ¹®À» ÅëÇØ¼­ ORACLE ¿¡¼­ÀÇ ÀÛ¾÷Áß ¹ß»ýÇÑ ¹®Á¦¸¦ C ¾îÇø®ÄÉÀ̼ǿ¡¼­ ¾Ë¼ö ÀÖµµ·Ï µµ¿ÍÁØ´Ù.

À̰ÍÀº ´ÜÁö SQLCA ¸¦ include ½ÃŰ´Â °ÍÀ¸·Î °¡´ÉÇϸç, ¿¡·¯¸¦ Ã¼Å©ÇØ¾ßµÉ ºÎºÐ¿¡¼­ °£´ÜÇÏ°Ô »ç¿ëÇÒ¼ö ÀÖ´Ù. ¿¹¸¦µé¾î ¿À¶óŬ ¼­¹ö¿¡ ¿¬°áÀ» ½ÃµµÇÏ°í ¿¬°á ½Ãµµ °á°ú¸¦ üũÇÏ°í ½Í´Ù¸é, ¾Æ·¡¿Í °°Àº °£´ÜÇÑ ¹æ¹ýÀ¸·Î ¿¡·¯¸¦ Á¦¾îÇÒ¼ö ÀÖ´Ù.

EXEC SQL INCLUDE SQLCA;

....
int main()
{
    ....
    EXEC SQL CONNECT :userid;

    // ¿¡·¯ °Ë»ç
    if (sqlca.sqlcode < 0)
    {
        // ÀÚ¼¼ÇÑ ¿¡·¯¸Þ½ÃÁö Ãâ·Â
        printf("%s\n", sqlca.sqlerrm.sqlerrmc);
        exit(0);
    }
}
			


2.5절. Proc¸¦ ÀÌ¿ëÇÑ ¾îÇø®ÄÉÀÌ¼Ç °³¹ß¹æ¹ý

ÀüüÀûÀ¸·Î º¸ÀÚ¸é ´ÙÀ½°ú °°Àº ¹æ¹ýÀ» ÅëÇØ¼­ Proc °³¹ßÀÌ ÀÌ·ç¾îÁø´Ù.

그림 1. Proc¸¦ ÀÌ¿ë ¿À¶óŬ DBÇÁ·Î±×·¡¹Ö °úÁ¤

º¸¸é ¾Ë°ÚÁö¸¸ ÀϹÝÀûÀÎ C ¾îÇø®ÄÉÀÌ¼Ç °³¹ß¹æ¹ý°ú ºñ±³Çؼ­ "Proc ÄÚµåÀÛ¼º", "Precomplie" °¡ µé¾î°£°Í¸¸ »©°í´Â µ¿ÀÏÇÏ´Ù´Â°É ¾Ë¼ö ÀÖÀ» °ÍÀÌ´Ù.


3절. ¼ÀÇÃÀÛ¼º

°¡Àå ºü¸¥ ÀÌÇØ¸¦ À§Çؼ­´Â ¿ª½Ã ¼ÀÇà ÀÛ¼º¸¸ÇÑ°Ô ¾ø´Ù. ÀÌ¹Ì ¸ðµç Å×½ºÆ® ȯ°æÀº °¡Ãß¾îÁ® ÀÖ´Ù°í °¡Á¤À» ÇÏ°í ¼ÀÇÃÀ» ÀÛ¼ºÇÒ °ÍÀÌ´Ù. ¼ÀÇà ÇÁ·Î±×·¥Àº "¿ìÆíÁÖ¼Ò °Ë»ö" ÇÁ·Î±×·¥ÀÌ´Ù.

¼ÀÇÃÇÁ·Î±×·¥Àº ¸ðµâº°·Î ºÐÇҵǾ Makefile ·Î °ü¸® µÉ°ÍÀ̸ç, Çì´õ ÆÄÀÏÀº include ¶ó´Â ¼­ºêµð·ºÅ丮¸¦ ¸¸µé°Í¾î¼­ °ü¸®ÇÏ°Ô µÈ´Ù. ´ÙÀ½Àº À̹ø ¿¹Á¦ÀÇ ½î¾² Æ®¸®±¸¼ºµµÀÌ´Ù.

 +--/---+--- Makefile      make ÆÄÀÏ
        |
        +--- main.pc       main ÇÔ¼ö¸¦ Æ÷ÇÔ
        |
        +--- myterm.pc     teminal Á¦¾î °ü·Ã ÇÔ¼ö
        |
        +--- zipcode.pc    DB¿¬°á¹× Äõ¸® °ü·Ã
        |
        +--- include ----+-- menu.h     ¸Þ´ºµé 
                         |
                         +-- myterm.h  
                         |
                         +-- zipcode.h
		

¼ÀÇà ¾îÇø®ÄÉÀ̼ÇÀº »ç¿ëÀÚ¿ÍÀÇ ÀÎÅÍÆäÀ̽º¸¦ À§Çؼ­ ANSI ¿Í termios ¸¦ Á¶ÇÕÇØ¼­ »ç¿ëÇÒ°ÍÀÌ´Ù. ANSI ´Â Ãâ·ÂÀÇ ¸ð¾ç - Ä¿¼­À̵¿, È­¸é Á¤¸® - À» Á¶Á¤Çϱâ À§Çؼ­ »ç¿ëµÇ¸ç, termios ´Â Å͹̳ΠƯ¼º(ÀÔÃâ·Â) À» Á¦¾îÇϱâ À§Çؼ­ »ç¿ëµÉ°ÍÀÌ´Ù.

¿¹¸¦µé¾î¼­ º¸Åë ÆÐ½º¿öµå ÀÔ·ÂÀ» À§Çؼ­´Â ÆÐ½º¿öµå¸¦ È­¸é¿¡ Ãâ·ÂÇÏÁö ¾Ê°í "*" ·Î ´ëÄ¡½ÃÄѼ­ Ãâ·ÂÇÏ°Ô µÈ´Ù. ÀÌ·¯ÇÑ ±â´ÉÀº termios ÀÇ ÅÍ¹Ì³ÎÆ¯¼º Á¦¾î¸¦ ÅëÇØ¼­ ±¸ÇöÇÏ°Ô µÈ´Ù. termios ´Â º°µµÀÇ ¹®¼­¸¦ ÀÌ¿ëÇØ¼­ ÀÚ¼¼È÷ ¼³¸íÇϵµ·Ï ÇÒ°ÍÀÌ´Ù.

ANSI ´Â Ä¿¼­ÀÇ ¿òÁ÷ÀÓ°ú È­¸éÁö¿ì±â, ¶óÀÎÁö¿ì±â µîÀÇ ±¸ÇöÀ» À§Çؼ­ »ç¿ëÇÑ´Ù.


3.1절. Makefile

¾ÆÁÖ °£´ÜÇÏ´Ù. ºÐ¼®Çϴµ¥ ¾î·Á¿òÀÌ ¾øÀ»°ÍÀÌ´Ù.

TARGET          = zipcode

CC              = gcc
PROC            = proc
LIB             = -L$(ORACLE_HOME)/lib -lclntsh
MYINC           = include/
PROCINC         = include=$(ORACLE_HOME)/precomp/public/ include=$(ORACLE_HOME)/rdbms/demo/ \
    include=$(ORACLE_HOME)/rdbms/public/ \
    include=$(ORACLE_HOME)/network/public/ 
CINC            = -I$(ORACLE_HOME)/precomp/public/ -I$(ORACLE_HOME)/rdbms/demo/ \
    -I$(ORACLE_HOME)/rdbms/public/ -I$(ORACLE_HOME)/network/public/ 

ORA_OPT         = PARSE=NONE RELEASE_CURSOR=YES MODE=ANSI
CC_OPT          =

OBJECT          = main.o \
                zipcode.o \
                myterm.o
ORA_GARBAGE     = *.dcl *.cod *.cud *.lis

######## implicit rules
.SUFFIXES: .pc .c

.pc.c:
    $(PROC) $* INCLUDE=$(MYINC) $(PROCINC) $(ORA_OPT)
.c.o:
    $(CC) -c -o $*.o $*.c -I $(MYINC) $(CINC)

####### build rules

all:            $(TARGET)

$(TARGET):      $(OBJECT)
    $(CC) -o $(TARGET) $(OBJECT) $(LIB)

main.c: main.pc
main.o: main.c zipcode.c myterm.c
zipcode.c : zipcode.pc
zipcode.o : zipcode.c
myterm.c : myterm.pc
myterm.o : myterm.c

clean:
    rm -f $(TARGET) $(OBJECT) $(ORA_GARBAGE) *.c 
			


3.2절. main.pc

#include <unistd.h>
#include <stdio.h>
#include <zipcode.h>
#include <myterm.h>
#include <termios.h>


int main()
{
    /* Å͹̳ΠÃʱâÈ­ */  
    termio_init();

    /* ·Î±×ÀÎ */  
    if (login(3) < 0)
    {
        login_error();
        exit(0);
    }    

    /* ·Î±×Àο¡ ¼º°øÇß´Ù¸é
     * ½ÇÁ¦ ÀÛ¾÷¿¡ µé¾î°£´Ù. 
     */
    search_zipcode();

    /* ÃÖÃÊ Å͹̳Π»óÅ·Πº¹¿ø½ÃŲ´Ù */  
    termio_default();
    return 1;
}
			


3.3절. myterm.pc

#include <unistd.h>
#include <stdio.h>

#include <zipcode.h>
#include <myterm.h>
/*
 * Å͹̳ΠÃʱâÈ­
 */
void termio_init()
{
    tcgetattr(0, &stored_settings);

    default_settings = stored_settings;
    tcsetattr(0, TCSANOW, &default_settings);

    stored_settings.c_lflag &= (~ICANON);
    tcsetattr(0, TCSANOW, &stored_settings);
}

void termio_default()
{
    tcsetattr(0, TCSANOW, &default_settings);
}

/* ÆÐ½º¿öµå¸¦ È­¸é¿¡ º¸ÀÌÁö ¾Ê±â À§Çؼ­
 * ÀÔ·ÂÀ» È­¸é¿¡ ¹ÝÇâ(echo) ÇÏÁö ¾Êµµ·Ï ¼³Á¤ÇÑ´Ù.
 */
void echo_off()
{
    struct termios new_settings;
    tcgetattr(0, &stored_settings);
    new_settings = stored_settings;
    new_settings.c_lflag &= (~ECHO);
    tcsetattr(0, TCSANOW, &new_settings);

    return;
}

/*
 * ±âº» Å͹̳Π»óÅ·ΠµÇµ¹¸°´Ù.
 */
void echo_on()
{
    tcsetattr(0, TCSANOW, &stored_settings);
    return ;
}
			


3.4절. zipcode.pc

½ÇÁúÀûÀ¸·Î ¿À¶óŬµ¥ÀÌŸ º£À̽º¿Í °ü·ÃµÈ ÀÛ¾÷À» ÇÏ´Â ÇÔ¼öµéÀº ¿©±â¿¡ Á¤ÀǵǾî ÀÖ´Ù. ±×¸® º¹ÀâÇÏÁö ¾ÊÀ¸´Ï ´ëÃæ ÈȾîºÁµµ ÀÌÇØ °¡´ÉÇÒ°ÍÀÌ´Ù.

#include <stdio.h>

#include <zipcode.h>
#include <myterm.h>
#include <menu.h>

EXEC SQL INCLUDE SQLCA;
/*
 * ÆÐ½º¿öµå¸¦ ¹Þ¾ÆµéÀδÙ.
 * echo_off ÇÔ¼ö¸¦ È£ÃâÇØ¼­
 * Űº¸µåÀÔ·ÂÀÌ ¹ÝÇâµÇÁö ¾Êµµ·ÏÇÑÈÄ
 * ŰÀÔ·ÂÀ» "*" ·Î ´ëüÇÑ´Ù.
 * ÀÔ·ÂÀ» ¸¶Ä£ÈÄ¿¡´Â echo_on ÇÔ¼ö¸¦ È£ÃâÇÏ¿©
 * ÀÔ·ÂÀ» ¹ÝÇâÇÑ´Ù.
 */
void get_pass(char *pass)
{
    char buf;
    int i = 0;
    echo_off();
    while ((buf=getc(stdin)) != '\n')
    {
        pass[i] = buf;
        printf("%c", '*');
        i++;
    }
    echo_on();
    return ;
}

/*
 * ´ÜÀÏ ¹®ÀÚ¸¦ ÀԷ¹ޱâ À§Çؼ­ »ç¿ëÇÑ´Ù.
 * getc ¸¦ ÀÌ¿ëÇÑ ´ÜÀÏ ¹®ÀÚ ÀԷ½Ã
 * °³Ç๮ÀÚ°¡ ¹ÝÇâµÇÁö
 * ¾Êµµ·Ï echo_off ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
 */
int ngetc()
{
    char buf;
    echo_off();
    buf = getc(stdin);
    if (buf != '\n')
        printf("%c", buf);
    echo_on();
    return buf;
}

/*
 * ¿©·¯ÁÙÀÇ ÀÔ·ÂÀ» ¹Þ±â À§Çؼ­ »ç¿ëÇÑ´Ù.
 * °³Ç๮ÀÚ´Â Á¦°ÅÇÑÈÄ µÇµ¹·ÁÁØ´Ù.
 */
void get_input(char *str)
{
    char buf;
    int i = 0;
    while ((buf=getc(stdin)) != '\n')
    {
        str[i] = buf;
        i++;
    }
    return ;
}
/*
 * ¿ìÆí¹øÈ£¸¦ Ãâ·ÂÇÑ´Ù.
 * ½ÇÁ¦ °Ë»öÀº dong ¸¸À» °¡Áö°í ÇÑ´Ù.
 */
int print_zipcode(char *city, char *dong)
{
    int state;
    int i;
    int running = 1;

    /*
     * DECLARE ¿µ¿ª
     */
    EXEC SQL BEGIN DECLARE SECTION;
        /*
         * Select ÇÑ µ¥ÀÌŸ°¡ µé¾î°¥ ±¸Á¶Ã¼ÀÌ´Ù. 
         * ÁÖÀÇÇØ¾ß ÇÒÁ¡Àº °¢ ¸â¹öº¯¼öÀÇ Å©±â¸¦ 
         * ÀâÀ»¶§ ½ÇÁ¦ ÇʵåÀÇ Å©±âº¸´Ù +1 ¸¸Å­ ´õÅ©°Ô 
         * ¹è¿­ °ø°£À» Àâ¾Æ¾ß ÇÑ´Ù´Â °ÍÀÌ´Ù. 
         * ½ÇÁ¦ zipcode table ÀÇ zipcode Çʵå´Â 7ÀÇ Å©±âÀÌ´Ù.
         * +1 ¸¸Å­ ´õ Å©°Ô Àâ´Â ÀÌÀ¯´Â ³Î°ªÀ» ÀúÀåÇϱâ À§ÇÔÀÌ´Ù.   
         */
        struct testdata
        {
            char zipcode[8];
            char sido[11];
            char gugun[15];
            char bunji[19];
            char dong[45];
            char numb[3];
        } mydata;
        char mdong[16];
        int page = 1;
        int page_per_list = 17;
        int start_listnum, end_listnum;
    EXEC SQL END DECLARE SECTION;

    /*
     * ¹®ÀÚ¿­ copy ¸¦ ÅëÇØ¼­ dong º¯¼ö¸¦
     * declare ¿µ¿ª¿¡¼­ ¼±¾ðµÈ ¿À¶óŬ º¯¼ö·Î º¹»çÇÑ´Ù.
     */
    strcpy(mdong, dong);
    strcat(mdong,"%");

    while(running)
    {
        int i;
        /* ÁÖ¼Ò¸®½ºÆ® ¿µ¿ª (5-17 ¶óÀÎ)À» Áö¿î´Ù */
        SCR_CLEAR2(5,17);
        MOVE_CURSOR(5, 1);

        /* Ãâ·ÂÇϰíÀÚ ÇÏ´Â ÁÖ¼Ò¸®½ºÆ® ¿µ¿ªÀ» °è»êÇÑ´Ù
         * page          : º¸°íÀÚ ÇÏ´Â ÆäÀÌÁö
         * end_listnum   : ÇöÀç ÆäÀÌÁö¿¡¼­ °¡ÀåÅ« ¸®½ºÆ®¹øÈ£
         * start_listnum : ÇöÀç ÆäÀÌÁöÀÇ ½ÃÀÛ ¸®½ºÆ® ¹øÈ£
         * page_per_list : ÇÑÆäÀÌÁö¿¡ º¸¿©Áà¾ßÇÒ ¸®½ºÆ® ¼ö (17)
         */
        end_listnum = page_per_list * page;
        start_listnum = end_listnum - page_per_list;

        /*
         * CURSOR À» ¸¸µç´Ù.
         * mysql ¿¡¼­ ¹üÀ§ÁöÁ¤À» À§ÇØ»ç¿ëÇÏ´Â limit ¸¦ ¿À¶óŬ¿¡¼­´Â
         * Á¦°øÇÏÁö ¾ÊÀ½À¸·Î, rownum À» ÀÌ¿ëÇÑ in-line view ¸¦ »ç¿ëÇÑ´Ù.
         */
        EXEC SQL DECLARE zip_cursor CURSOR FOR
            SELECT * FROM
            (
                SELECT ZIPCODE, SIDO, GUGUN, BUNJI, DONG, ROWNUM NUMB
                FROM ZIPCODE WHERE DONG like : mdong
            ) 
            WHERE NUMB > : start_listnum
            AND NUMB < : end_listnum;

        printf("dong : (%s)\n", mdong);
        if (sqlca.sqlcode !=0 )
        {
            printf("ERROR\n");
            return -1;
        }

        /*
         * Ä¿¼­¸¦ »ç¿ëÇϱâ À§Çؼ­ ¿¬´Ù.
         */
        EXEC SQL OPEN zip_cursor ;

        /*
         * ¿­¸° Ä¿¼­¿¡¼­ FETCH ÀÛ¾÷Áß ´õÀÌ»ó FETCH ÇÒ
         * µ¥ÀÌŸ°¡ ¾øÀ¸¸é DO ÀÌÈÄÀÇ ¹®ÀÎ break ¸¦ ½ÇÇàÇÑ´Ù.
         */
        EXEC SQL WHENEVER NOT FOUND DO break;
        for (i=0; ;i++)
        {
            /*
             * FETCH ÇÑ µ¥ÀÌŸ´Â mydata ±¸Á¶Ã¼¿¡ ÀÔ·ÂÇÑ´Ù.
             */
            EXEC SQL FETCH zip_cursor INTO: mydata;

            /*
             * proc ¿¡¼­´Â FETCH ÇÑ ·¹ÄÚµåÀÇ Æ¯Á¤Çʵ忡 µ¥ÀÌŸ°¡
             * ¾øÀ»°æ¿ì ¿¡·¯(-1405) 󸮸¦ ÇÑ´Ù. 
             * ±×·¯³ª ÇʵåÀÇ Æ¯¼º¿¡ µû¶ó¼­ NULL ÀÌ µÉ¼öµµ ÀÖÀ½À¸·Î
             * ÀÌ ¿¡·¯´Â ¹«½ÃÇÏ°í ³Ñ¾î°¡µµ·Ï ÇÑ´Ù.
             */
            if (sqlca.sqlcode < 0)
            {
                if (sqlca.sqlcode != -1405)
                {
                    break; 
                }
            }

            /* 
             * ¿ìÆí¹øÈ£ µ¥ÀÌŸ Ãâ·Â 
             */
            printf("%s %s %s %s\n", 
                    mydata.zipcode,   
                    mydata.sido, mydata.gugun,
                    mydata.dong, mydata.bunji);
        }

        /* ÆäÀÌÁö Ãâ·Â */
        MOVE_CURSOR(22, 1);
        LINE_CLEAR;
        printf("page : %d", page);

        /* 
         * ¿­¸° Ä¿¼­´Â ´õÀÌ»ó »ç¿ëÇÏÁö ¾ÊÀ»°æ¿ì
         * ´Ý¾ÆÁÖ¾î¾ß ÇÑ´Ù.
         * ±×·¸Áö ¾ÊÀ»°æ¿ì ¸Þ¸ð¸® ´©¼ö°¡ »ý±æ¼ö ÀÖ´Ù. 
         */
        EXEC SQL CLOSE zip_cursor;

        /*
         * move_page ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ŰÀÔ·ÂÀ»
         * ¹Þ¾Æµé¿©¼­ ÆäÀÌÁö À̵¿À» ÇÑ´Ù.
         */
        if (i == 16 || page > 1)
        {
            int ans;
            while(1)
            {
                ans = move_page();
                if (ans == NEXT)
                {
                    if (i == 16)
                    {
                        page++;
                        break;
                    }
                }
                else if (ans == PREV)
                {
                    if (page > 1)
                    {
                        page--;
                        break;
                    }
                }
                else
                    return 1;
            }
        }
        else
        {
            return 1;
        }
    }
}

/*
 * ·Î±×ÀÎ
 * check_num ¸¸Å­ ¾ÆÀ̵ð¿Í ÆÐ½º¿öµå¸¦ ¹¯´Â´Ù.
 */
int login(int check_num)
{
    int loop = 1;
    char id[16];
    char pass[16];
    SCR_CLEAR;

    while(1)
    {
        memset(pass, 0x00, 16);
        memset(id, 0x00, 16);
        MOVE_CURSOR(10,5);
        printf("%s\n", login_prompt);
        if (loop > 1)
        {
            MOVE_CURSOR(15, 23);
            printf("Login Failure !! %s", pass);
        }
        MOVE_CURSOR(12, 34);
        get_input(id);

        MOVE_CURSOR(13, 34);
        get_pass(pass); 

        if ((dbconnect(id, pass) < 0))
        {
            if (loop == check_num)
            {
                return -1;
            }
            #ifdef __DEBUG 
            MOVE_CURSOR(22, 1);
            printf("%s", sqlca.sqlerrm.sqlerrmc);
            #endif
        }
        else
        {
            MOVE_CURSOR(22, 1);
            printf("Connection Success !!");
            return 1;
        }
        loop++;
    }
}

/*
 * ¾ÆÀ̵ð¿Í, ÆÐ½º¿öµå¸¦ ÀÌ¿ëÇØ¼­
 * ·Î±×ÀÎÀ» ½Ç½ÃÇÑ´Ù.  
 */
int dbconnect(char *id, char *pass)
{
    EXEC SQL BEGIN DECLARE SECTION;
        char loginid_pass[40];
    EXEC SQL END DECLARE SECTION;
    
    sprintf(loginid_pass, "%s/%s@oracle", id, pass);
    EXEC SQL CONNECT: loginid_pass;

    return sqlca.sqlcode;
}
 
/*
 * µ¿À̸§À» ÀÌ¿ëÇØ¼­ ¿ìÆï¹øÈ£ °Ë»öÀ» ÇÑ´Ù.
 */ 
int search_zipcode()
{   
    char city[16];
    char dong[16];
    int running = 1;
    SCR_CLEAR;

    MOVE_CURSOR(4,2);
    printf("%s", hr);

    MOVE_CURSOR(23,2);
    printf("%s", hr);

    while(running)
    {
        MOVE_CURSOR(1,1);
        printf("%s\n", query_prompt);
        memset(city, 0x00, 16);
        memset(dong, 0x00, 16);
        MOVE_CURSOR(2, 13);
        get_input(city);

        MOVE_CURSOR(3, 13);
        get_input(dong);

        if (strlen(city) == 0 && strlen(dong) == 0)
        {
            if (question_end() == YES)
                running = 0;
        }
        else
        {
            MOVE_CURSOR(5, 1);
            print_zipcode(city, dong);
        }
    }

    /*
     * ¿À¶óŬ¼­¹ö¿ÍÀÇ ¿¬°áÀ» ²÷´Â´Ù.
     */
    EXEC SQL COMMIT WORK RELEASE;

    /*
     * È­¸éÀ» Ŭ¸®¾î Çϰí Ä¿¼­¸¦
     * óÀ½È­¸éÀ¸·Î µÇµ¹¸°´Ù.
     */
    SCR_CLEAR;
    MOVE_CURSOR(1, 1);
}

/* ÆäÀÌÁö À̵¿ °ü·Ã */
int move_page()
{
    char ans;
    while(1)
    {
        MOVE_CURSOR(24, 2);
        LINE_CLEAR;
        printf("%s", "ÆäÀÌÁö À̵¿ (P:ÀÌÀü N:´ÙÀ½ Q:Á¾·á)");
        ans = ngetc();
        switch(ans)
        {
            case('N'):
            case('n'):
                return NEXT;
                break;
            case('P'):
            case('p'):
                return PREV;
                break;
            case('q'):
            case('Q'):
                return QUIT;
                break;
        }
    }
}

/* Á¾·áÇÒ°ÍÀÎÁö¸¦ ¹¯´Â´Ù */
int question_end()
{
    char ans;
    while(1)
    {
        MOVE_CURSOR(24, 2);
        LINE_CLEAR;
        printf("%s", ques_end);  
        ans = ngetc();
        switch(ans)
        {
            case('y'):
            case('Y'):
                return YES;
                break;
            case('n'):
            case('N'):
                return NO;
                break;
            default:
                break;
        }
    }
}

int login_error() 
{
    MOVE_CURSOR(23, 1);
    printf("Login failure!!\n");
    return -1;
}
			


3.5절. include/menu.h

¸Þ´º¿Í °ü·ÃµÈ º¯¼öµéÀÌ ¼±¾ðµÇ¾î ÀÖ´Ù.

#ifndef _MENU_H_
#define _MENU_H_

#define SCR_CLEAR printf("^[[2J")
#define MOVE_CURSOR(x,y) printf("^[[%d;%dH", x,y)
#define WAIT_INPUT(x) printf("%s", x); getchar()
#define chop(str) str[strlen(str)-1] = '\0'
#define LINE_CLEAR printf("^[[K")

#define SCR_CLEAR2(x, y) for (i=0; i < y; i++) \
{ \
    MOVE_CURSOR(x+i, 1);\
    printf("^[[2K");\
}\
MOVE_CURSOR(x, 1);

#define STDIN 0
#define YES 1
#define NO  0 
#define UNKNOWN 2 

#define NEXT 1
#define PREV 0
#define QUIT 2
char *login_prompt =
"
                    +----------+-----------------+
                    | ¾Æ ÀÌ µð | ____________    |
                    | ÆÐ½º¿öµå | ____________    |
                    +----------+-----------------+
                    |                            |
                    +----------+-----------------+
";

char *query_prompt =
"
 µµ½ÃÀ̸§ : __________
 µ¿ ÀÌ ¸§ : __________
";

char *hr =
"=============================================================================";

char *question = "¼±Åà (Y,N,X) : ";
char *ques_end = "Á¾·áÇϽðڽÀ´Ï±î (Y/N) ? ";

#endif
			


3.6절. myterm.h

myterm.pc ÇÔ¼ö¿¡ ´ëÇÑ ¼±¾ð

#ifndef _MYTERM_H_ 
#define _MYTERM_H_
#include <termios.h>
static struct termios stored_settings;
static struct termios default_settings;
void termio_init();
void termio_default();
void echo_off();
void echo_on();

#endif
			


3.7절. zipcode.h

zipcode.pc ÇÔ¼ö¿¡ ´ëÇÑ ¼±¾ð

#ifndef _ZIPCODE_H_
#define _ZIPCODE_H_

void get_pass(char *pass);
int ngetc();
int login(int);
int dbconnect();
int search_zipcode();
int question_end();

void get_input(char *str);
print_zipcode(char *city, char *dong);
int login_error();

#endif
			


4절. Å×½ºÆ®

À§ÀÇ ¾îÇø®ÄÉÀ̼ÇÀ» ½ÇÇàÇÏ¸é ´ÙÀ½°ú °°Àº È­¸éµéÀ» º¸¿©ÁÙ°ÍÀÌ´Ù. Âü°í·Î µµ½ÃÀ̸§°Ë»öÀº ÇÏÁö ¾Ê°í ´ÜÁö "µ¿À̸§" À¸·Î¸¸ °Ë»öÇÑ´Ù.

·Î±×ÀÎ


                    +----------+-----------------+
                    | ¾Æ ÀÌ µð | system______    |
                    | ÆÐ½º¿öµå | *******_____    | 
                    +----------+-----------------+
                    |                            |
                    +----------+-----------------+
		

°Ë»ö

 µµ½ÃÀ̸§ : __________
 µ¿ ÀÌ ¸§ : ¿ª»ï______
 =============================================================================
dong : (¿ª»ï%)
135-706 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ °ø¹«¿ø¿¬±Ý°ü¸®°ø´Ü                  
135-703 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ °úÇбâ¼úȸ°ü                        
135-707 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ³²¿µºôµù                            
135-977 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ·Î´ãÄÚºôµù                          
135-709 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ºòÅ丮¾Æºôµù                        
135-979 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ »ïºÎºôµù                            
135-980 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ »ï¼º¿ª»ïºôµù                        
135-751 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ »ï¼ºÁ¦ÀϺôµù                        
135-768 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ »ïÀÏÇÁ¶óÀÚ¿ÀÇǽºÅÚ                  
135-711 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ »ïÈïºôµù                            
135-917 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ¼ºÁöÇÏÀÌÃ÷1Â÷ºôµù                   
135-717 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ¼ºÁöÇÏÀÌÃ÷3Â÷ºôµù                   
135-984 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ½ºÅ¸Å¸¿ö                            
135-718 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ¾Æ°¡¹æºôµù                          
135-978 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ¾ÆÁÖºôµù                            
135-748 ¼­¿ï       °­³²±¸         ¿ª»ï1µ¿ ¿©»ïºôµù                            
page : 1
 =============================================================================
 ÆäÀÌÁö À̵¿ (P:ÀÌÀü N:´ÙÀ½ Q:Á¾·á)
		
N/n, P/p ¸¦ ÀÌ¿ëÇØ¼­ ÆäÀÌÁö À̵¿ÀÌ °¡´ÉÇÏ´Ù.


5절. °á·Ð

ÀÌ»ó proc Çùֿ¡ ´ëÇÑ Á»´õ ±íÀÌ ÀÖ´Â ³»¿ëÀ» ´Ù·ç¾î º¸¾Ò´Ù. ±×·¯³ª ¿©±â¿¡¼­ ´Ù·é ³»¿ëÀº Àüü proc ³»¿ë¿¡ ºñÇϸé Á¤¸» ¸Àº¸±âÁ¤µµ ÀÌ´Ù. ¸»ÇßµíÀÌ proc ´Â ±× ÀÚü¸¸À¸·Îµµ Ã¥¸î±ÇºÐ·®ÀÌ ½±°Ô ³ª¿À´Â ¹æ´ëÇÑ ºÐ·®ÀÌ´Ù. ¶ÇÇÑ PL/SQL ¿¡ ´ëÇÑ ³»¿ëµµ ¾î´ÀÁ¤µµ ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù.

À̹®¼­´Â ¾îµð±îÁö³ª ºÎ´ã¾øÀÌ proc ÇùÖÀ» Á¢ÇÒ¼ö ÀÖµµ·Ï Çϱâ À§ÇÑ Áöħ¼­ ÀÌ´Ù. (ÀÏ´Ü ÄÄÆÄÀÏ ÇÒÁÙÀº ¾Ë¾Æ¾ß ±íÀÌ µé¾î°¡µçÁö ¸»µçÁö ÇÒÅ״ϱî)

proc Çùֿ¡ ´ëÇÑ ´õ¿í ±íÀº ³»¿ëÀº °¢ÀÚÀÇ ¸òÀÌ µÉ°ÍÀÌ´Ù.

EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.