«á¤@¶ «e¤@¶ ¦^¥Ø¿ý ¦^º¶ |
18.3.4.1 ¾A¤Æ·§z¡@ ¡@ ©Ò¿×¾A¤Æ´N¬O±N®à±À³¥ÎÂà¤Æ¬°Client/ServerÀ³¥Î¡C¡@¡@¾A¤Æ¬O¤@ӫܽÆÂøªº¥DÃD¡A³oùؤ£¸Ô²ÓÁ¿z¡C¥»¸`±N¤¶²Ð¾A¤Æ Delphi À³¥Îµ{¦¡¤¤³Ì«nªº¤è±¡C¡@¡@¾A¤Æªº¥Dn¤è±¦³¡G ¡@¡@¡´ ±N¸ê®Æ®w±q®à±°ò¥x¨ì¦øªA¾¹ªº¾A¤Æ¡@ ¡´ ±NÀ³¥Îµ{¦¡Âà¤Æ¬°Client/Serverªº¾A¤Æ¡@ ¡@¡@¾A¤ÆÁÙ»Ýn¹ê²{±q®à±Àô¹Ò¨ì Client/ServerÀô¹ÒªºÂà¤Æ¡C¡@¡@®à±¸ê®Æ®w©M SQL¦øªA¾¹¸ê®Æ®w¦b³\¦h¤è±¦³¤£¦P¤§³B¡C¨Ò¦p¡G ¡@¡´ ®à±¸ê®Æ®w¥Î©ó¦P¤@®É¨è³æ¥Î¤áªº¦s¨ú¡A¦Ó¦øªA¾¹¥Î©ó¦h¥Î¤á¦s¨ú ¡@¡´ ®à±¸ê®Æ®w¬O±¦V°O¿ýªº¡A¦Ó¦øªA¾¹¬O±¦V¶°¦Xªº¡@ ¡´ ®à±¸ê®Æ®w±N¨CÓªí¦sÀx¦b¿W¥ßªº¤å¥ó¤¤¡A ¦Ó¦øªA¾¹±N©Ò¦³ªºªí¦sÀx¦b¸ê®Æ®w¤¤Client/ServerÀ³¥Î¥²¶·¸Ñ¨M§ó·sªº°ÝÃD¡A³Ì½ÆÂøªº¬OÁp±µ¡Bºô¸ô©M¨Æ°È±±¨î¡@ 18.3.4.2 ¾A¤Æ¸ê®Æ®w¡@ ¡@¡@¾A¤Æ¸ê®Æ®w¥]§t¤U¦C¨BÆJ¡G ¡@¡@¡´ ¦b®à±¸ê®Æ®wµ²ºcªº°ò¦¤W¡A©w¸q¦øªA¾¹¤Wªº¤¸¼Æ¾Ú¡@ ¡´ ±N¼Æ¾Ú±q®à±Âà¤Æ¨ì¦øªA¾¹¤¤ ¡@¡´ ¸Ñ¨M¤U¦C°ÝÃD¡G ¡@ ¡´ ¼Æ¾Ú«¬¦¡®t²§ ¡@ ¡@¡´ ¼Æ¾Ú¦w¥þ©Ê©M§¹¾ã©Ê ¡@ ¡´ ¨Æ°È±±¨î ¡@¡@ ¡´ ¼Æ¾Ú¦s¨úÅv ¡@¡@¡@¡´ ¼Æ¾Ú¦Xªk©Ê ¡@¡@¡@¡´ Âê©w¡@ ¡@Delphi´£¨Ñ¤F¨âºØ¤èªk¾A¤Æ¤@Ó¸ê®Æ®w¡C¡@ ¡´ ¨Ï¥ÎDatabase Desktop¤u¨ã¡A¿ï¾Ü¿ï¾ÜªíTools/Utilities/Copy to©R¥O±N¸ê®Æ®wªí±q®à±¤è¦¡«þ¨©¨ìSQL®æ¦¡ ¡´ «Ø¥ßÀ³¥ÎTBatchMove³¡¥óªºÀ³¥Îµ{¦¡¡@ ¡@¡@³o¨âºØ¤èªk³£¥i¥H±Nªíµ²ºc©M¼Æ¾Ú±q®à±¼Æ¾Ú·½Âà¤Æ¨ì¦øªA¾¹¤W¡C¨Ì¾a³o¨Ç¸ê®Æ®w¡A¥i¯à»Ýn§ïÅܵ²ªGªí¡C¨Ò¦p¡A¥i¯à·Q¶i¦æ¤£¦P¼Æ¾Ú«¬¦¡ªº¬M®g¡C ¡@¡@¤]¥i¥H±N¤U¦C¯S©º¥[¤J¸ê®Æ®w¡G ¡´ §¹¾ã©Ê¬ù§ô ¡´ ¯Á¤Þ¡@ ¡´ °»´ú¬ù§ô ¡´ ¦sÀx¹Lµ{©MIJµo¾¹¡@ ¡´ ¨ä¥¦¦øªA¾¹¯S©º¡@ ¡@¡@¦pªG¥Î SQL¸}¥»©M¦øªA¾¹¼Æ¾Ú©w¸q¤u¨ã©w¸q¤¸¼Æ¾Ú·|§ó¦³®Ä¡CµM«á¥Î«e±¤¶²Ðªº¨âºØ¤èªkÂಾ¼Æ¾Ú¡C¦]¬°¦pªG¬O¤â¤u©w¸q¸ê®Æ®wªí¡ADatabase Desktop©MTBatchMove ³¡¥ó±N¥u«þ¨©¼Æ¾Ú¡C¡@ 18.3.4.3 ¾A¤ÆÀ³¥Îµ{¦¡¡@ ¡@¡@¦b²z½×¤W¡A³]p¥Î¨Ó¦s¨ú§½³¡¼Æ¾Úªº DelphiÀ³¥Îµ{¦¡°µ«Ü¤Öªº×§ï´N¥i¥H¦s¨ú»·ºÝ¦øªA¾¹¤Wªº¼Æ¾Ú¡C¦pªG¦b¦øªA¾¹¤W©w¸q¾A¦Xªº¼Æ¾Ú·½¡A§A´N¯à±NÀ³¥Îµ{¦¡«ü¦V¦s¨ú¥¦¡A³o¥u»Ý²³æ¦a§ïÅÜÀ³¥Îµ{¦¡¤¤TTable©ÎTQuery³¡¥óªºDatabaseNameÄÝ©Ê¡C¡@¡@¹ê»Ú¤W¡A¦b¦s¨ú§½³¡©M¹Lµ{¼Æ¾Ú·½¤§¶¡¦³³\¦h«nªº¤£¦P¤§³B¡C Client/ServerÀ³¥Îµ{¦¡¥²¶·¸Ñ¨M¤j¶qªº¦b®à±À³¥Î¤¤©Ò¨S¦³ªº°ÝÃD¡C¡@¡@¥ô¦ó DelphiÀ³¥Îµ{¦¡³£¯à¥ÎTTable©ÎTQuery³¡¥ó¦s¨ú¼Æ¾Ú¡C®à±À³¥Îµ{¦¡³q±`³£¬O¨Ï¥ÎTTable³¡¥ó¡C·í¾A¤Æ¨ìSQL¦øªA¾¹¤W®É¡A¥ÎTQuery·|§ó¦³®Ä¡A¦pªGÀ³¥Îµ{¦¡nÀ˯Á¤j¶q°O¿ý¡A«hTQuery³¡¥ón²¤³Ó¤@Äw¡C¡@¡@¦pªGÀ³¥Îµ{¦¡¨Ï¥Î²Îp©Î¼Æ¾Ç¨ç¼Æ¡A¨º»ò¦b¦øªA¾¹¤W³q¹L¦sÀx¹Lµ{°õ¦æ³o¨Ç¨ç¼Æ·|§ó¦³®Ä¡C¦]¬°¦sÀx¹Lµ{°õ¦æ§ó§Ö¡A¨Ï¥Î¦sÀx¹Lµ{ÁÙ¥i¥H´î¤Öºô¸ôt¸ü¡A¯S§O¬O¤j¶q¦æ¼Æ¾Úªº¨ç¼Æ¡C ¡@¡@¨Ò¦p¡Apºâ¤j¶q°O¿ýªº¼Ð·Ç®t¡G ¡@¡@¡´ ¦pªG¸Ó¨ç¼Æ¦b¥Î¤áºÝ°õ¦æ¡A©Ò¦³ªºÈ±q¦øªA¾¹¤WÀ˯Á¥X¨Ó¨Ã°e¨ì¥Î¤áºÝ¡A¾ÉPºô¸ô¾Ö¶ë¡@¡@¡´ ¦pªG¸Ó¨ç¼Æ¦b¦øªA¾¹ºÝ°õ¦æ¡A«hÀ³¥Îµ{¦¡¥u»Ýn¦øªA¾¹¤Wªºµª®×¡@ ¡@ ¡@ ¡@ ¡@ ¡@ 18.4 Delphi ¥Î¤á/¦øªA¾¹À³¥Î¹ê¨Ò¤ÀªR¡@ ¡@¡@¥»¸`¤¤±Ä¥Îªº¹ê¨Ò¬O Delphi2.0¸ê®Æ®wªº¨Ò¤lCSDEMO¡CCSDEMO¬ODelphi¥Î¤á/¦øªA¾¹µ{¦¡³]pªº¥Ü¨Òµ{¦¡¡A¥¦±Ä¥Îªº¸ê®Æ®w¦øªA¾¹¬OLocal InterBase Server¡CCSDEMO ¸û¦n¦a½d¨Ò¤FBDEÀô¹Òªº²ÕºA¡AInterBASE Server¶i¶¥¥\¯àÀ³¥Î¡ASQL¦øªA¾¹Áp±µ¡AIJµo¾¹À³¥Î¡B¦sÀx¹Lµ{µ{¦¡³]p©M¨Æ°È±±¨î§Þ³Nµ¥¡A¨ã¦³¸û°ªªº°Ñ¦Ò»ùÈ¡C¥»¸`Á¿z¤U¦C¤º®e¡G¡@ ¡´ ¸ê®Æ®wÀô¹Ò¤¶²Ð¡@¡@¡´ TDatabaseªºÀ³¥Î ¡@¡´ ¤£¦P¸ê®Æ®wªíªº¤Á´«¡@ ¡´ IJµo¾¹µ{¦¡³]p¡@¡@¡´ ¦sÀx¹Lµ{µ{¦¡³]p ¡@¡´ ¨Æ°È±±¨îÀ³¥Î¡@ 18.4.1 ¸ê®Æ®wÀô¹Ò¤¶²Ð¡@ ¡@¡@¥»¨Ò¤¤±Ä¥Îªº¸ê®Æ®w¦øªA¾¹¬O Local InterBase Server¡CLocal InterBase¬OInterBase Serverªº³æ¥Î¤áª©32¦ì¡B¬Û®eANSI SQL¡CLocal InterBase¤ä´©¥Î¤á/¦øªA¾¹À³¥Î¦b³æ¾÷¤Wªº¶}µo©M´ú¸Õ¡A¨Ã¥B¥i¥H«Ü®e©ö¦a¾A¤Æ¨ìInterBase Server¤W¡C¦]¦¹¡A¶}µo¥Î¤á/¦øªA¾¹À³¥Î±Ä¥ÎLocal InterBase§@¬°ì«¬¶}µoÀô¹Ò¬O«Ü¤è«Kªº¡C¡@ 18.4.1.1 IBLOCAL ªºBDE°Ñ¼Æ¡@ ¡@¡@¥»¨Ò¤¤ªº SQL¸ê®Æ®w¬OIBLOCAL¡C¥¦¬O¥ÑBDE²ÕºA¤u¨ã(BDECFG32.EXE)³]©w°Ñ¼ÆÈ¡C¥¦ªº¦U¶µ°Ñ¼ÆȦC©ó¤Uªí¡G¡@ ªí18.13 IBLOCALªº¦U¶µ°Ñ¼ÆÈ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w °Ñ ¼Æ ¦W °Ñ ¼Æ È ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X TYPE INTRBASEPATH SERVER NAME C:\INTRBASE\EXAMPLES\EMPLOYEE.GDB USER NAME SYSDBA OPEN MODE READ/WRITE SCHEMA CACHE SIZE 8 LANGDRIVER SQLQRYMODE SQLPASSTHRU MODE SHARED AUTOCOMMIT SCHEMA CHCHE TIME -1 MAX ROWS -1 BATCH COUNT 200 ENABLE SCHEMA CACHE FALSE SCHEMA CACHE DIR ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¡@ 18.4.1.2 ¸ê®Æ®wµ²ºc¤¶²Ð¡@ ¡@IBLOCAL¸ê®Æ®wªºµ²ºc³£¬O¥ÑInterBase¦øªA¾¹¤u¨ã¤¬°Ê¦¡SQL¤u¨ã(ISQL)©w¸qªº¡C¡@¡@¥Î ISQL©w¸q¸ê®Æ®w¡Aº¥ýn¥ÎCreate Database©R¥O«Ø¥ß¸ê®Æ®w¡A«Ø¥ßªº·s¸ê®Æ®w¤@¯ë¬O¥HGDB¬°Àɮתþ¥[¦W¡C«Ø¥ß¦n«á¡A´N¥i¥H¥ÎSQL»y¨¥©w¸q¸ê®Æ®wªí¡A¨Ò¦p«Ø¥ßEMPLOYEEªíªºSQL»y¥y¦p¤U¡G¡@ ©w¸qºôÄæ¦ì¼Ðñ¼Æ¾Ú«¬¦¡¡G¡@ CREATE DOMAIN FIRSTNAME AS VARCHAR(15); CREATE DOMAIN LASTNAME AS VARCHAR(20); CREATE DOMAIN COUNTRYNAME AS VARCHAR(15); CREATE DOMAIN EMPNO AS SMALLINT; CREATE DOMAIN DEPTNO AS CHAR(3) CHECK (VALUE = '000' OR (VALUE > '0' AND VALUE <= '999') OR VALUE IS NULL); CREATE DOMAIN JOBCODE AS VARCHAR(5) CHECK (VALUE > '99999'); CREATE DOMAIN JOBGRADE AS SMALLINTCHECK (VALUE BETWEEN 0 AND 6); CREATE DOMAIN SALARY AS NUMERIC(15, 2) DEFAULT 0 CHECK (VALUE > 0); ¡@ «Ø¥ßEMPLOYEEªí¡G ¡@ CREATE TABLE EMPLOYEE (EMP_NO EMPNO NOT NULL, FIRST_NAME FIRSTNAME NOT NULL, LAST_NAME LASTNAME NOT NULL, PHONE_EXT VARCHAR(4), HIRE_DATE DATE DEFAULT 'NOW' NOT NULL, DEPT_NO DEPTNO NOT NULL, JOB_CODE JOBCODE NOT NULL, JOB_GRADE JOBGRADE NOT NULL, JOB_COUNTRY COUNTRYNAME NOT NULL, SALARY SALARY NOT NULL, FULL_NAME COMPUTED BY (last_name || ', ' || first_name), PRIMARY KEY (EMP_NO)); ¡@¡@¡@ CHECK»y¥y¬Oµ¹¸ê®Æ®wÄæ¦ì¨úȽd³ò¥[¬ù§ô±ø¥ó¡CPRIMARY_KEY»y¥y¬Oµ¹ªí«Ø¥ßÃöÁä¦r¯Á¤Þ¡C¡@¡@¦pªk¬¶¨î¡A´N¥i¥H©w¸q IBLOCAL¤¤ªº©Ò¦³ªí¡C¡@¡@ IBLOCAL¤¤ªºªí¥]¬A¡G¡@ EMPLOYEE CUSTOMER DEPARTMENT EMPLOYEE_PROJECT PROJECT SALES SALARY_HISCORY ¡@¦U¸ê®Æ®wªí¤¤ªº¤º®e¦p¤U¡G ¡@ ªí18.14 EmployeeDemoDB¤¤¦U¸ê®Æ®wªíªº¤º®e ¡@¡@ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@¡@¡@¡@¸ê®Æ®wªí¦W¡@¡@¡@¡@¡@¡@¡@¡@ªí¤¤¤º®e ¡@¡@ ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X ¡@ ¡@ ¡@EMPLOYEE ¶±û¸ê°T ¡@¡@¡@CUSTOMER ¥Î¤á¸ê°T DEPARTMENT ³¡ªù¸ê°T EMPLOYEE_PROJECT ¶±ût³dªº¤uµ{ PROJECT ¤uµ{¸ê°T SALES ¾P°â¸ê°T SALARY_HISTORY ¶±ûÁ~¤ô½Õ¾ãªº¾ú¥v¸ê°T ¡@¡@ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@ ¨CÓ¸ê®Æ®wªí¤¤³£©w¸q¤FÃöÁäÄæ¦ì¡CÃö©ó¸ê®Æ®wªí¤¤ªºÄæ¦ì¦W¡B«¬¦¡¡B¤j¤p¡A³oùؤ£¦AÂØz¡C ¡@ 18.4.2 À³¥Îµ{¦¡¤ÀªR ¡@ 18.4.2.1 TDatabase³¡¥óªº¨Ï¥Î ¡@ ¡@¡@CSDEMOµ{¦¡¤¤©w¸q¤F¤@Ó¸ê®Æ®w¼Ò¸s²Õ³¡¥ó????TDmEmployee¡A¥¦¬OÄ~©Ó©óTDataModule¡CTDataModule¬O¦bDelphi2.0¤¤¤~¥X²{ªº±Mªù©ñ¸m¼Æ¾Ú¦s¨ú³¡¥ó(¦pTDatabase¡BTTable©MTQueryµ¥)ªº®Ø¬[¡C¨ä¥¦¯A¤Î¸ê®Æ®w¦s¨úªºµ¡Åé¡A¥un¦buses»y¥y¤¤´¡¤J¸ê®Æ®w¼Ò¸s²Õ©Ò¦bªº®w³æ¤¸¡A¸Óµ¡Åé¤Wªº¸ê®Æ®w³¡¥ó´N¥i¤Þ¥Î¬ÛÀ³ªº¸ê®Æ®w¦s¨ú³¡¥ó¡C ¡@¡@¦bTDmEmployee¤¤©w¸q¤F¤@ÓTDatabase«¬¦¡ªº³¡¥ó¡X¡XEmployeeDatabase¡CEmployeeDatagaseªº¥DnÄݩʤÎÄÝ©ÊȦp¤U¡G ¡@ ªí18.15 EmployeeDatabase³¡¥ó¥DnÄݩʪº¨úÈ ¡@¡@ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@ ¡@¡@ÄÝ©Ê¡@¡@¡@¡@¡@¡@¡@¡@ÄÝ©ÊÈ ¡@¡@ ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X ¡@ ¡@ AliasName IBLOCAL DatabaseName EmployeeDemoDB KeepConnection True LoginPrompt False TransIsolation tiReadCommitted Params USERNAME = SYSDBA PASSWORD = masterkey Connected True ¡@¡@¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@ AliasNameÄÝ©Ê©Ò«ü©wªºIBLOCAL¡A¥²¶·¤w¸g¦bBDE¤¤²ÕºA¦n¡ADatabaseNameÄÝ©Ê«ü©wn¨Ï¥Îªº¸ê®Æ®w¦W¡A¸Ó¸ê®Æ®w¦W¬O¥ÑÀ³¥Îµ{¦¡¦Û¤v©w¸qªº¡A¦]¦¹¤£¤ÏÀ³¨ìBDE¤¤¡A¸ÓÄÝ©ÊȳQTTable¡BTQueryµ¥DataSet³¡¥ó¤Þ¥Î¡A¨Ã¥B¥X²{¦bDataSet³¡¥óªºDatabaseName ¤U©Ô¦¡¦C¥Ü¤è¶ô¤¤¡C¥»¨Ò¤¤ªº¡§EmployeeDemoDB¡¨¡A³QEmployeeTable¡ASalesTableµ¥©Ò¦³DataSet³¡¥ó¤Þ¥Î¡C Connected¬°Trueªí©ú¡AÀ³¥Îµ{¦¡»P¸ê®Æ®w±N«O«ùÁp±µ¡C KeepConnectionÄݩʬ°True¡Aªí©ú¦h¦¸¥´¶}©MÃö³¬EmployeeDemoDB¸ê®Æ®w¤¤ªº¥ô·Nªí¡AÀ³¥Îµ{¦¡±N©l²×»P¸ê®Æ®w«O«ùÁp±µ¡A³o¬Ù«o¤F«½Æµù¥Uªº¶}¾P¡C LoginPrompt Äݩʬ°False¡Aªí©úÀ³¥Îµ{¦¡¦Û°Ê³B²z»P¸ê®Æ®wªºÁp±µµù¥U¡A¦]¦¹¡AParamsÄݩʤ¤©w¸q¤Fµù¥Uªº¥Î¤á¦W©M±K½X¡G ¡@ ¡@¡@USERNAME = SYSDBA PASSWORD = masterkey ¡@ TransIsolation Äݩʬ°tiReadCommittedªí©ú¡A¦pªG¦s¦b¦hÓ¦P®É¨Æ°È¡A«h¬Y¤@¨Æ°È¥u¤¹³\Ū¥Ñ¨ä¥¦¨Æ°È´£¥æ¤Fªº¼Æ¾Ú¡C¡@¡@µ{¦¡¤¤ EmployeeDatabaseªºÀ³¥ÎÁÙ»P¨Æ°È±±¨îµ¥¦³Ãö¡C¤U¤å¤¤·|¤¶²Ð³o¤è±ªº¤º®e¡C¡@ 18.4.2.2 ¤£¦P¸ê®Æ®wªíªº¤Á´«¡@ ¡@¡@¦b³\¦h¸ê®Æ®wÀ³¥Î¤¤³£n¦b¤£¦P¸ê®Æ®wªí¤§¶¡¬Û¤¬¤Á´«¡A¥HÅTÀ³¥Î¤á¿é¤J±ø¥ó©Î¨t²Îª¬ºAªºÅܤơC³o®É¡A©¹©¹»Ýn¯S§Oªº³B²z¡A¨Ò¦p§ïÅܹC¼Ð§Îª¬©ÎÁôÂüƾڧïÅܵ¥¡A¤×¨ä¬O¦b¥Î¤á /¦øªA¾¹À³¥Îµ{¦¡¤¤¡C¦]¬°¬O¥ÎSQL»y¥y¦s¨ú»·ºÝ¸ê®Æ®w¡A¦³®ÉÁÙn¦b¦øªA¾¹ºÝ°õ¦æpºâ¥ô°È¡A©Ò¥H¥Î¤áºÝªº¼Æ¾ÚÅܤƷ|¦³¤@©wªº¶¡¹j¡A¦]¦¹À³¸ÓÅý¥Î¤á©ú¥Õµo¥Í¤F¤°»ò¡C¤U±¬OCSDEMO¦b¸ê®Æ®wªí¤Á´«®Éªº³B²z¿ìªk¡G¡@ procedure TFrmViewDemo.ShowTable( ATable: string );begin Screen.Cursor := crHourglass; { ¦V¥Î¤á´£¥Ü¥Ø«e¾Þ§@ª¬ºA }VaryingTable.DisableControls; { ÁôÂüƾÚÅÜ¤Æ }VaryingTable.Active := FALSE; { Ãö³¬ì¨Óªº¸ê®Æ®wªí }VaryingTable.TableName := ATable; { §ó·s¸ê®Æ®wªí¦W }VaryingTable.Open; { ¥´¶}¸ê®Æ®wªí }VaryingTable.EnableControls; { Åã¥Ü©Ò§@ªº×§ï } Screen.Cursor := crDefault; { «·s³]©w¹C¼Ð§Îª¬ } end;¡@ ¡@¡@crHourglass«¬¹C¼Ðªí©ú¥¿¦b°õ¦æSQL¬d¸ß¡CDisableControls©MEnableControlsªº§@¥Î¬OÁôÂéMÅã¥Ü¼Æ¾ÚÅܤơC ¡@ 18.4.2.3 InterBaseIJµo¾¹(Trigger)ªºÀ³¥Î ¡@ ¡@¡@¦bCSDEMOÀ³¥Îµ{¦¡¤¤¡Aºt¥ÜIJµo¾¹À³¥Îªºµ¡Åé¬OTFromTriggerDemo¡F ¡@ ¦b¸Óµ¡Å餤¥]§t¨âÓTDBGridª«¥ó¡CDBGrid1Åã¥ÜEmployeeTable¤¤ªº¼Æ¾Ú¡ADBGrid2Åã¥ÜSalaryHistoryTable¤¤ªº¼Æ¾Ú¡C¥¦Ìªº¥DnÄݩʤÎÄÝ©ÊȦp¤U¡G¡@ ªí18.16 EmlpoyeeTable³¡¥ó¥DnÄݩʪº¨úÈ ¡@ ¡@¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@ ¡@¡@ÄÝ¡@©Ê¡@¡@¡@¡@¡@¡@ ÄÝ ©Ê È ¡@ ¡@¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X ¡@ ¡@ ¡@DatabaseName EmployeeDemoDBIndexFieldName Emp_No TableName EMPLOYEE ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¡@ ªí18.17 SalaryHistoryTable³¡¥ó¥DnÄݩʪº¨úÈ ¡@ ¡@¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@¡@¡@ÄÝ¡@©Ê¡@¡@¡@¡@¡@ ¡@ÄÝ ©Ê ªí¡@ ¡@ ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X ¡@ ¡@ DatabaseName EmployeeDemoDBIndexFieldName Emp_No ¡@¡@ ¡@ MasterFields Emp_No MasterSource EmployeeSource TableName SALARY_HISTORY ¡@ ¡@¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@ ¡@¡@³o¨âÓªí¤§¶¡¦s¦b¨âºØÃö«Y¡G ¡@¡@¡´ ³s±µÃö«Y EmployeeTableªº°O¿ýÅܤƮɡASalaryHistoryTableªº¼Æ¾Ún§@¬ÛÀ³ªºÅܤơC³oºØ³s±µÃö«Y¬O³q¹L¯Á¤Þ¨Ó¹ê²{ªº¡C ¡@¡@¡´ ¼Æ¾Ú¤@P©Ê ¹ïEmployeeTable¤¤ªºSalaryÄæ¦ìªºÈ§@ק沈¶·¤Ï¬M¨ìSalaryHistoryTable¤¤¡ASalaryHistoryTableºûÅ@ªº¬OSalaryÅܤƪº¾ú¥v¸ê°T¡C³oºØ¼Æ¾Ú¤@P©Ên¨D¦b¥»µ{¦¡¤¤¬O³q¹LIJµo¾¹¹ê²{ªº¡C ¡@¡@IJµo¾¹¬O¦bSQL¦øªA¾¹ºÝ°õ¦æªº¤@¬qµ{¦¡¡A¥¦¦b¦øªA¾¹ºÝ³QIJµo°õ¦æ§¹¦¨¤@©wªº¼Æ¾Úpºâ¥ô°È¡C ¡@¡@¤U±¬OInterBase¦øªA¾¹¤W»PEmployeeªí¬ÛÃöªºÄ²µo¾¹µ{¦¡¡G ¡@ Triggers on Table EMPLOYEE: SAVE_SALARY_CHANGE, Sequence: 0, Type: AFTER UPDATE, Active AS BEGIN IF (old.salary <> new.salary) THEN INSERT INTO salary_history (emp_no, change_date, updater_id, old_salary, percent_change) VALUES ( old.emp_no, 'now', user, old.salary, (new.salary - old.salary) * 100 / old.salary); END ¡@ ¡@¡@¦]¬°Ä²µo¾¹¬O¬ÛÀ³©óEMPLOYEEªí¤Wªº¼Æ¾Úקï¥Ñ¦øªA¾¹¦Û°ÊIJµo°õ¦æªº¡A©Ò¥H¦b¥Î¤áÀ³¥Îµ{¦¡¤W¨S¦³Å㦡ªº©I¥s¡C¦b¥Î¤áºÝ¦³¥´¶}¨ÃÅã¥Ü¸ê®Æ®wªí¤º®eªºµ{¦¡©M·íSALARY_HISTORYªí¤¤¼Æ¾ÚÅܤƮɪº§ó·sÅã¥Üªº¾Þ§@¡C ¡@ procedure TFrmTriggerDemo.FormShow(Sender: TObject); begin DmEmployee.EmployeeTable.Open; DmEmployee.SalaryHistoryTable.Open; end; ¡@ procedure TDmEmployee.EmployeeTableAfterPost(DataSet: TDataSet); begin { ¤@Ó¶±ûªºÁ~¤ôÅܤƱNIJµoÁ~¤ô½Õ¾ã¾ú¥v°O¿ýªºÅܤÆ, ¦]¦¹¡A¦pªGSalaryHistory¥´¶}ªº¸Ü¡A´N»Ýn§ó·sÅã¥Ü }with SalaryHistoryTable do if Active then Refresh; end; ¡@ 18.4.2.4 ¦sÀx¹Lµ{µ{¦¡³]p¡@ ¡@¡@¦sÀx¹Lµ{¤]¬O SQL¦øªA¾¹¤Wªº¤@¬qµ{¦¡¡A¥¦±µ¦¬¿é¤J°Ñ¼Æ¡A¦b¦øªA¾¹ºÝ°õ¦æ¡A¨Ã±Nµ²ªGªð¦^¥Î¤áºÝ¡A¦sÀx¹Lµ{¬O¥²¶·¦b¥Î¤áÀ³¥Îµ{¦¡¤¤Å㦡©I¥sªº¡C¡@¡@¹ï©ó¸ê®Æ®wªí¤¤¤j¶q°O¿ýªº²Îp©M¨ç¼Æpºâ¡A¦sÀx¹Lµ{¬O«Ü¦³¥Î¡A³o¼Ë¥i¥H±N«½Æ©Êpºâ¥ô°ÈÂà´«¨ì¦øªA¾¹¡A´£°ª¸ê®Æ®wÀ³¥Îªº©Ê¯à¡C ¡@ Delphi¤¤¦³¨âÓ³¡¥ó¯à¾Þ§@»·ºÝ¸ê®Æ®w¦øªA¾¹¤Wªº¦sÀx¹Lµ{¡GTQuery©MTStoredProc¡C1. TQuery ªº¦sÀx¹Lµ{µ{¦¡³]pCSDEMO ¤¤ºt¥Ü¥ÎTQuery©I¥s¦sÀx¹Lµ{ªºµ¡Åé¬OTFrmQueryProc¡C¡@¡@¡@ TFrmQueryProc¤¤¦³¨âÓTDBGrid ³¡¥ó¡CDBGrid1Åã¥ÜEmployeeTable¤¤ªº¼Æ¾Ú¡CDBGrid2Åã¥ÜProjectªí¤¤ªº¼Æ¾Ú¡C¨Ï¥Î¦sÀx¹Lµ{ªºTQuery³¡¥ó¦W¬°EmployeeProjectsQuery¡A¥¦ªº§@¥Î¬O«Ø¥ßEmployee ªí©MProject ªíªº³s±µ¡A¥H¹ê²{·íDBGrid1¤¤°O¿ý§ïÅܮɡADBGrid2¤¤ªº¼Æ¾Ú§@¬ÛÀ³ªº§ïÅÜ¡C¨ãÅ骺³s±µ¥ô°È¬O¥Ñ¦øªA¾¹¤Wªº¦sÀx¹Lµ{Get_Emp_Proj§¹¦¨¡C¤U±¬OGet_Emp_Projªºµ{¦¡¡G¡@ PROCEDURE Get_Emp_ProjBEGIN FOR SELECT proj_id FROM employee_project WHERE emp_no = :emp_no INTO :proj_id DO SUSPEND;END ¡@ EMP_NO INPUT SMALLINT PROJ_ID OUTPUT CHAR(5) ¡@¡@¡@¸Ó¹Lµ{±a¨âӰѼơG ¡@¡@ EMP_NO¬O¿é¤J°Ñ¼Æ¡A«¬¦¡¬OSMALLINT.PROJ_ID ¬O¿é¥X°Ñ¼Æ¡A«¬¦¡¬OCHAR(5) ¡@¡@¡@¬ÛÀ³¦a¡A EmployeeProjectsQueryªº¥DnÄݩʦp¤U¡G¡@ ªí18. 18 EmployeeProjectsQuery³¡¥ó¥DnÄݩʪº¨úÈ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@¡@¡@ÄÝ¡@©Ê¡@¡@¡@¡@¡@¡@¡@ÄÝ ©Ê È ¡@ ¡@¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡@ ¡@ DatabaseName EmployeeDemoDBParams EMP_No( ¿é¤J°Ñ¼Æ¡ASmallint«¬¦¡)SQL Select * from Get_Emp_Proj(:EMP_NO) ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¡@ TQuery ³¡¥ó¬O¦bSQL»y¥y¤¤ª½±µ©I¥s¦sÀx¹Lµ{¡C¡@¡@¤U±¬O¥Î¤áºÝªºµ{¦¡¡G ¡@ procedure TFrmQueryProc.FormShow(Sender: TObject);begin DmEmployee.EmployeeTable.Open; EmployeeSource.Enabled := True; with EmployeeProjectsQuery do if not Active then Prepare; end; ¡@¡@¡@¥Î PrepareÅ㦡¦a·Ç³ÆSQL»y¥y¡AÁö«D¥²¶·¡A¦ý¥i¥HÀu¤ÆSQLªº°õ¦æ¡C¡@ procedure TFrmQueryProc.EmployeeDataChange(Sender: TObject; Field: TField);begin EmployeeProjectsQuery.Close; EmployeeProjectsQuery.Params[0].AsInteger := DmEmployee.EmployeeTableEmp_No.Value; EmployeeProjectsQuery.Open; ¡@WriteMsg('Employee ' + DmEmployee.EmployeeTableEmp_No.AsString + ' is assigned to ' + IntToStr(EmployeeProjectsQuery.RecordCount) + ' project(s).'); end;¡@ ¡@¡@¸Ó¨Æ¥ó³B²z¹Lµ{»P EmployeeSourceªºOnDataChangeÄݩʬÛÁp¡C¥Î©ó·íEmployeeTable¼Æ¾Ú°O¿ýÅܤƮɡA×¥¿¦sÀx¹Lµ{ªº¿é¤J°Ñ¼Æ¡A¨Ã°õ¦æSQL»y¥y¡C¡@¡@ 2. TStoredProc³¡¥óªº¦sÀx¹Lµ{µ{¦¡³]p¡@¡@ TStoredProc Delphi ±Mªù¥Î¨Ó¨Ï¥Î¦øªA¾¹¦sÀx¹Lµ{ªº³¡¥ó¡CCSDEMO ¤¤ºt¥Ü¥ÎTStoredProc©I¥s¦sÀx¹Lµ{ªºµ¡Åé¬OTFrmExecPr¡@¡@¦bµ{¦¡°õ¦æ¤¤¡A·í«ö¤U ShipOrder«ö¶s¡An¨D¹ïORED_STA_TUSµ¥Äæ¦ìªº¤º®e§@קï¥HºûÅ@¸ê®Æ®wªº¤@P©Ê¡CÄæ¦ì¤º®eªº×§ï¥ô°È¥Ñ¦øªA¾¹¤Wªº¦sÀx¹Lµ{SHIP_ORDER§¹¦¨¡CSHIP_ORDEªºµ{¦¡¦p¤U¡G¡@ PROCEDURE SHIP_ORDERDECLARE VARIABLE ord_stat CHAR(7); DECLARE VARIABLE hold_stat CHAR(1); DECLARE VARIABLE cust_no INTEGER; DECLARE VARIABLE any_po CHAR(8); BEGIN SELECT s.order_status, c.on_hold, c.cust_no FROM sales s, customer c WHERE po_number = :po_num AND s.cust_no = c.cust_no INTO :ord_stat, :hold_stat, :cust_no; IF (ord_stat = "shipped") THEN BEGIN EXCEPTION order_already_shipped; SUSPEND; END ELSE IF (hold_stat = "*") THEN BEGIN EXCEPTION customer_on_hold; SUSPEND; END ¡@FOR SELECT po_number FROM sales WHERE cust_no = :cust_no AND order_status = "shipped" AND paid = "n" AND ship_date < 'NOW' - 60 INTO :any_po DO BEGIN EXCEPTION customer_check; ¡@UPDATE customer SET on_hold = "*" WHERE cust_no = :cust_no;¡@ SUSPEND; END ¡@UPDATE sales SET order_status = "shipped", ship_date = 'NOW' WHERE po_number = :po_num; SUSPEND; END ¡@Parameters: PO_NUM INPUT CHAR(8) ¡@¡@¡@¸Ó¹Lµ{¥u±a¦³¤@Ó¿é¤J°Ñ¼Æ¡G PO_NUM¡A«¬¦¡¬OCHAR(8)¡C¡@¡@¦b¥Î¤áºÝ¨Ï¥Î¸Ó¹Lµ{ªº TStoreProc³¡¥ó¬OShipOrderProc¡A¨ä¥DnÄݩʦp¤Uªí¡G¡@ ªí18.19 ShipOrderProc³¡¥ó¥DnÄݩʪº¨úÈ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@¡@¡@ÄݩʦW¡@¡@¡@¡@¡@¡@¡@¡@¡@ ÄÝ ©Ê È¡@ ¡@ ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡@ ¡@¡@DatabaseName EmployeeDemoDBParamBindMode pbByName Params PO_NUM( ¿é¤J°Ñ¼Æ¡AString«¬¦¡)StoredProcName SHIP_ORDER ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¡@ ¡@¡@¥Î¤áºÝ°õ¦æ SHIP_ORDERªºµ{¦¡¦p¤U¡G¡@ procedure TFrmExecProc.BtnShipOrderClick(Sender: TObject);begin with DmEmployee do begin ShipOrderProc.Params[0].AsString := SalesTable['PO_NUMBER']; ShipOrderProc.ExecProc; SalesTable.Refresh; end; end; ¡@¡@¡@·í¥Î¤á«ö ShipOrder«ö¶s®É¡A°õ¦æ³o¬qµ{¦¡¡Cµ{¦¡¤¤¥ý·Ç³Æ¿é¤J°Ñ¼Æ¡A¥ÎExecProc¤èªk°õ¦æ¦sÀx¹Lµ{¡C©I¥s SalesTable.Refresh¤èªk¨ê·s¼Æ¾ÚÅã¥Ü¡C¡@¡@¦b CSDEMOÀ³¥Îµ{¦¡¤¤¥t¤@ӨϥΦsÀx¹Lµ{ªºTStoredProc³¡¥ó¬ODeleteEmployeeProc¡C¥¦§¹¦¨ªº¥ô°È¬O¸Ñ°£Employeeªí¤¤ªº°O¿ý¡A¨Ãקï©Ò¦³¬ÛÃöªºªí¡A ¥HºûÅ@¼Æ¾Úªº¤@P©Ê¡C¨äÄݩʦp¤U¡G¡@ ªí18.20 DeleteEmployeeProc³¡¥ó¥DnÄݩʪº¨úÈ ¡@ ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w ¡@¡@¡@ÄݩʦW¡@¡@¡@¡@¡@¡@¡@¡@¡@ ÄÝ ©Ê È ¡@ ¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X¡X ¡@¡@¡@DataBaseName EmployeeDemoDBParamBindMode PbByName Params EMP_NUM( ¿é¤J°Ñ¼Æ¡A¾ã«¬)StoredProcName DELETE_EMPLOYEE ¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¡@ ¡@¡@¦sÀx¹Lµ{ DELETE_EMPLOYEEªºµ{¦¡¦p¤U¡G¡@ PROCEDURE DELETE_EMPLOYEEDECLARE VARIABLE any_sales INTEGER; BEGIN any_sales = 0; SELECT count(po_number) FROM sales WHERE sales_rep = :emp_num INTO :any_sales; IF (any_sales > 0) THEN BEGIN EXCEPTION reassign_sales; SUSPEND; END UPDATE department SET mngr_no = NULL WHERE mngr_no = :emp_num; UPDATE project SET team_leader = NULL WHERE team_leader = :emp_num; DELETE FROM employee_project WHERE emp_no = :emp_num; DELETE FROM salary_history WHERE emp_no = :emp_num; DELETE FROM employee WHERE emp_no = :emp_num; SUSPEND; END ¡@Parameters: EMP_NUM INPUT INTEGER ¡@¡@¡@±q¤Wz¦sÀx¹Lµ{ªº¨Ò¤l¤¤¡A§Ú̬ݨì¦sÀx¹Lµ{¦bºûÅ@¦øªA¾¹¤Wªº¼Æ¾Ú¤@P©Ê¤è±¦³«Ü±jªº¯à¤O¡A¥¦¸`¬Ù¤F¨t²Î¶}¾P¡A´£°ª¤F¥Î¤áºÝªº©Ê¯à¡C ¡@ 18.4.2.5 ¨Æ°È±±¨îµ{¦¡³]p¡@ ¡@¡@¦b¥Î¤á /¦øªA¾¹À³¥Îµ{¦¡¤¤¡A¨Æ°È±±¨î¬O¤@¶µ«Ü«nªº§Þ³N¡C¥¦¹ï©ó´£°ª¨t²Îªº¥i¾a©Ê¡AºûÅ@¼Æ¾Ú¤@P©Ê¦³µÛ«nªº·N¸q¡C¡@¡@ Delphi¤¤´£¨Ñ¤F¨Æ°ÈªºÁô¦¡©MÅ㦡¨âºØ±±¨î¤èªk¡C¨ä¤¤Å㦡±±¨îªº©Ê¯à¸û°ª¡A¤U±¤¶²ÐDelphi¨Æ°ÈÅ㦡±±¨îªºµ{¦¡³]p¤èªk¡C¡@¡@ Delphi¾á·í¨Æ°È±±¨î¥ô°Èªº³¡¥ó¬OTDatabase ¡CTDatabase ¥Î©ó¨Æ°È±±¨îªºÄݩʬOTransIsolation¡A¤èªk¦³StartTranstion¡BCommit©MRollback¡CÃö©ó³o¨ÇÄÝ©Ê©M¤èªk§@¥Î©M¨Ï¥Î¤èªk½Ð°Ñ¾\¥Î¤á/¦øªA¾¹¨Æ°ÈºÞ²z¡C¡@¡@¦b CSDEMO¤¤TDatabase ³¡¥ó¬°EMployeeDatabase¡A¨äTransIsolationÄÝ©ÊȬ°tiReadCommitted¡A·N¬°¦pªG¦s¦b¦hÓ¦P®É¨Æ°È¦s¨ú¸ê®Æ®w¡A«h¨ä¤¤¥ô¤@¨Æ°È¥u¯àŪ¨ä¥¦¨Æ°È´£¥æªº¤F¼Æ¾Ú¡C¡@¡@ CSDEMO¤¤ºt¥Ü¨Æ°È±±¨îªºµ¡Åé¬OTFrmTransDemo¡C¡@¡@ DBGrid1¤¤Åã¥ÜEmployeeTable¤¤ªº¤º®e¡C·íµøµ¡Åã¥Ü®É¡AEmployeeDatabase¶}©l¤@¦¸¨Æ°È±±¨î¨Ã¿E¬¡EmployeeTable¡G¡@ procedure TFrmTransDemo.FormShow(Sender: TObject);begin DmEmployee.EmployeeDatabase.StartTransaction; DmEmployee.EmployeeTable.Open; end; ¡@·íµøµ¡³QÃö³¬©ÎÁôÂîɡAEmployeeDatabase´£¥æ¨Æ°È¡G ¡@ procedure TFrmTransDemo.FormHide(Sender: TObject); begin DmEmployee.EmployeeDatabase.Commit; end; ¡@ ¡@¡@µøµ¡¤¤¦³¨âÓ«ö¶sBtnCommitEdits©MBtnUndoEdits¡C«ö¤UBtnCommitEdits«ö¶s±N´£¥æ¥Ø«e¨Æ°È¡A¨Ã¶}©l·sªº¨Æ°È±±¨î¨Ã¨ê·s¼Æ¾Ú¡C ¡@ procedure TFrmTransDemo.BtnCommitEditsClick(Sender: TObject); begin if DmEmployee.EmployeeDatabase.InTransaction and (MessageDlg('Are you sure you want to commit your changes?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then begin DmEmployee.EmployeeDatabase.Commit; DmEmployee.EmployeeDatabase.StartTransaction; DmEmployee.EmployeeTable.Refresh; end else MessageDlg('Can''t Commit Changes: No Transaction Active', mtError, [mbOk], 0); end; ¡@ ¡@¡@«ö¤UBtnUndoEdits«ö¶s±NªðÂà¥Ø«e¨Æª«¡A«ì´_ì¨Óªº¼Æ¾Ú¡A¶}©l·sªº¨Æ°È±±¨î¡A¨Ã¨ê·s¼Æ¾ÚªºÅã¥Ü¡C ¡@ procedure TFrmTransDemo.BtnUndoEditsClick(Sender: TObject); begin if DmEmployee.EmployeeDatabase.InTransaction and (MessageDlg('Are you sure you want to undo all changes made during the ' + 'current transaction?', mtConfirmation, [mbYes, mbNo], 0) = mrYes) then begin DmEmployee.EmployeeDatabase.Rollback; DmEmployee.EmployeeDatabase.StartTransaction; DmEmployee.EmployeeTable.Refresh; end else MessageDlg('Can''t Undo Edits: No Transaction Active', mtError, [mbOk], 0); end; |
«á¤@¶ «e¤@¶ ¦^¥Ø¿ý ¦^º¶ |