VFP ·R¥ÎªÌªÀ°Ï ­º­¶ VFP ·R¥ÎªÌªÀ°Ï
¥»°Q½×°Ï¬° Visual Foxpro ·R¥ÎªÌ¸gÅç¥æ¬yªº¦a¤è, ½Ð¦h¦h§Q¥Î"·j´M"ªº¥\¯à, ¥ý¬d¬Ý¬Ý¦³µL«e¨Ò¥i´`, ¦pªGÁÙ¦³¤£À´ªº¦Aµo°Ý. ³¡¥÷¥DÃD¦³ªþ¥[ÀÉ®×, ¶·¥ýµù¥U¦¨¬°ªÀ°Ï©~¥Á¤~¥i¥H¤U¸ü.
 
 ±`¨£°ÝÃD±`¨£°ÝÃD   ·j´M·j´M   ·|­û¦Cªí·|­û¦Cªí   ·|­û¸s²Õ·|­û¸s²Õ   ·|­ûµù¥U·|­ûµù¥U 
 ­Ó¤H¸ê®Æ­Ó¤H¸ê®Æ   µn¤JÀˬd±zªº¨p¤H°T®§µn¤JÀˬd±zªº¨p¤H°T®§   µn¤Jµn¤J

¤@­Ó¨Ï¥Î»¡©ú¡AÃö©ócursoradapterÃþªº[Âà¶K]

 
µoªí·s¥DÃD   ¦^ÂÐ¥DÃD    VFP ·R¥ÎªÌªÀ°Ï ­º­¶ -> VFP °Q½×°Ï
¤W¤@½g¥DÃD :: ¤U¤@½g¥DÃD  
µoªí¤H ¤º®e
joson



µù¥U®É¶¡: 2003-06-16
¤å³¹: 4


²Ä 1 ¼Ó

µoªíµoªí©ó: ¬P´Á¤G ¤Q¤ë 28, 2003 9:03 pm    ¤å³¹¥DÃD: ¤@­Ó¨Ï¥Î»¡©ú¡AÃö©ócursoradapterÃþªº[Âà¶K] ¤Þ¨¥¦^ÂÐ

¤@­Ó¨Ï¥Î»¡©ú¡AÃö©ócursoradapterÃþªº
½Ķ¡G¥|ºû

vfp8³Ì¿E°Ê¤H¤ßªºÅܤƬO CursorAdapter Ãþ¡A¥¦爲¤£¦Pªº¸ê®Æ·½´£¨Ñ³q¥Îªº¸ê®Æ¤¶­±¡C
¤U­±¤¶²Ð«ç¼Ë¥Î CursorAdapter §ïÅܦb VFP 8 ¤¤³s±µ¸ê®Æªº¤è¦¡,¥]¬A¡Anative tables, ODBC, OLE DB, XML. ¡C

CursorAdapter Ãþ¬O VFP 8 ¶}µo²Õªº³Ìµ¹¤H¦L¶H²`¨èªº¦¨´N¤§¤@¡C ¥¦±N·|§ïÅܳ\¦h¶}µoªÌ³s±µ¦UºØ¤£¦Pªº¸ê®Æ¨Ó·½ªº¤è¦¡¡C ¶}µo¤p²Õ¦b VFP ¦s¨ú¸ê®Æªº¤è¦¡¤è­±§@¤F­«­n§ïÅÜ,±N¥»¦a©M»·ºÝ¸ê®Æ³s±µ¤è¦¡¶i¦æ¤F²Î¤@¡C¥t¥~¡A³Ð«Ø CursorAdapter Ãþ¹ï¨º¨Ç¤w¸g¼ô½m¨Ï¥Îµø¹Ï©MSPT¤H¨Ó»¡¨Ã¤£¶O¤O¡C¹ï¨Ï¥ÎADO RecordSets ©ÎXML¥iÂX®i¼Ð¥Ü»y¨¥¤å¥óªº¤H¤]¤£¶O¤O¡C

CursorAdapter Ãþªº¿W¯S¤§³B¦b©ó¡A¥¦¬O²Ä¤@­Ó´£¨Ñ¥»¦a´å¼Ð¡BODBC¡BADO¡BXML¸ê®Æ·½³s±µªº°òÃþ¡A¦b¤@­ÓÃþùØ­±¹ê²{¤F©Ò¦³³s±µ¥\¯à¡C´«¥y¸Ü»¡¡A­n±NODBC¸ê®Æ·½¡AADO RecordSet ©ÎXML¥iÂX®i¼Ð¥Ü»y¨¥¤å¥ó½Ķ¦¨¤@­Ó VFP ´å¼Ð¡ACursorAdapter Ãþ§¹¥þ¥i¥H³Ó¥ô¡C

§A©Î³\·|»¡ CursorAdapter ¬O¸û¦­ª©¥»¤¤¥»¦aµø¹Ï©M»·ºÝµø¹Ï§Þ³Nªº´À¥N (ª`·N: VFP 8¤¤¤´µM«O¯d³o¨Ç¥\¯à). ¦ý¬O¦b¤@¨Ç±¡§Î¤¤¡A¥¦¤]¥N´À¤FSPT, ¥H¤Î´î¤Ö¤F¨Ï¥ÎADO©MXML®Éªº¥N½X¶q¡A¥i¥Hª½±µ¨Ï¥ÎADO©MXML¡C
CursorAdapter ªº³Ì¤j¦n³B¬O¡A»Ý­n¦b¦P¤@­Óµ{¦¡¤º³s±µ¨ì¦h­Ó¸ê®Æ·½ªº®É­Ô¡A¥¦爲§A´£¨Ñ¤è«K¡CÁ|¨Ò»¡¡A¦pªG§Aªºµ{¦¡¤j³¡¤À¼Æ¾Ú¨Ó¦Û SQL server¡A¦ý¬O¦P®É»Ý­n»PXML¥iÂX®i¼Ð¥Ü»y¨¥³s±µ,CursorAdapter ¥i¥H¾ã¦X³o¨âºØ±¡ªp¡A¨Ïµ{¦¡¨ú¦^ªº¸ê®Æ§@爲VFPªº´å¼Ð¡C

¥t¥~ªº¤@­Ó¨Ò¤l¬O¸ê®Æ²{¦b³QÀx¦s¦b VFP ªí¤¤ , ¦ý¬O­p¹º­n²¾¨ì¤@­Ó¸ê®Æ®w¦øªA¾¹ , ¤ñ¦p SQL server©ÎOracle¡C §A»Ý­n¥ý«Ø¥ß¤@²Õ VFP CursorAdapter Ãþ¡A¥²­nªº®É­Ô¥H SQL server¥H¥~ªº¸ê®Æ®w¥N´À³o¨ÇÃþ¡C

¦ý¬O,´N¶H§Ú­Ì¯à¶]¤§«e¥²¶·¾Ç·|¨«¤@¼Ë,¥ý·§Äý¤@¤U CursorAdapter Ãþ©M¥¦ªº¯S©Ê¡C µM«á¡A¨Ï¥Î CursorAdapter Ãþ¨Ó³]­p¸ê®ÆÃþ¬O¤ñ¸û®e©öªº¡C

«Ø¥ß²Ä¤@­Ó CursorAdapter Ãþ¡A¶H¨ä¥LÃþ¤@¼Ë¡A¾Ç²ß«ç¼Ë¨Ï¥Î¥¦ªº³Ì¦n¿ìªk¬OÁA¸Ñ«Ø¥ß¹Lµ{¡C²Ä¤@¦¸«Ø¥ß³o¨ÇÃþªº®É­Ô½ÆÂøµ{«×§C¤@¨Ç,§Ú­Ì¶}©l¥Î CursorAdapter Ãþ¦s¨ú VFP ¥»¦aªº¸ê®Æ¡C ³o«Ü¶H¨Ï¥Î¥»¦aµø¹Ï¨ú¦^ VFP ¥»¦aªíªº¸ê®Æ¡C µy«á¦b³o¤@½g¤å³¹¤¤¡A§Ú­Ì±N·|¨Ï¥Î¥t¤@­Ó CursorAdapter Ãþ³s±µ¨ì SQL server¸ê®Æ®w¡AODBC©MXML¡C
­º¥ý¡A§A¦³¤G­Ó¤èªk«Ø¥ß CursorAdapter ¡C §A¯à¨Ï¥Î¸ê®ÆÀô¹Ò«Ø¥ß¡A¤]¥i¥H¤â°Ê³q¹Lµ{¦¡©ÎÃþ³]­p¾¹¨Ó³Ð«Ø¤@­Ó¸g¹L¤@­ÓCursorAdapterÃþ ¡C ³o¤@­Ó¨Ò¤l±N·|¨Ï¥Î¸ê®ÆÀô¹Ò«Ø¥ß¡F¸û¿ðªº¨Ò¤l±N·|¤â°Ê«Ø¥ß.

¦pªG§A¤£¼ô±x VFP 8 Åܤƫ᪺¸ê®ÆÀô¹Ò, §A¥i¯à»{爲¦b³]­pÀô¹Ò¤U³Ð«Øªº CursorAdapter ¥u¯à¦bªí³æ¤¤¨Ï¥Î,¤£¯à¥Î©óÃþ¡C µM¦Ó¡A VFP 8 ¤¤¤w¸g§ïµ½¤F³]­pÀô¹Ò¡A¦]¦¹¤£»Ý­n¦bªí³æ¤¤´N¥i¥H³Ð«Ø¡C

¥Îcreat class©R¥O³Ð«Ø¤@­Ó·sªº¸ê®ÆÀô¹ÒÃþ¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

½T©w±q¤U©Ô²M³æ¤¤¿ï¾Übased on¸ê®ÆÀô¹ÒÃþ(dataenvironment) ¡CÃþ¦W爲Tests,©ÒÄÝÃþ®w¦W爲tests.vcx.

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

³Ð«ØªºÃþ¦bÃþ³]­p¾¹¤¤¥X²{«á¡A¥kÁ䳿À»Data Environment ¡A¿ï¾Übuilder,°_°Ê¸ê®ÆÀô¹Ò«Ø¥ß¦V¾É¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

¦b¸ê®Æ·½Ãþ«¬¶µ¤U¡Aª`·N¥i¿ïªº¿ï¶µ¡C ¦]爲²Ä¤@­Ó¨Ò¤l±N·|³s±µ¨ì¥»¦aªº VFP ªí,¿ï¾Ünative¡C ¿ï¾Ü§¹¥H«á, ¨Ï¥Î¡¥¬Ù²¤¸¹¡¦«ö¶s¿ï¾Ü Northwind ¸ê®Æ®w¡]§Ú³oùجOgzdata¸ê®Æ®w¡^¡C (Àq»{¦ì¸m¬O c:\ program files\microsoft visual foxpro 8\ sample\northwind\ northwind.dbc)


¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

¤U¤@¨B,ÂIcursors ­¶, ¥¦ªì©l­È¬OªÅªº¡C ¦b¦Cªí®Ø¤¤,¿ï¾Ünew«ö¶s¥Î CursorAdapter ³]­p¾¹³Ð«Ø¤@­Ó·sªº CursorAdapter Ãþ¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

­º¥ý¡A§AÀ³¸Ó¬Ý¬ÝProperties­¶¡A³oùØ´£¨Ñ¿ï¶µ¨Ó¿ï¾ÜÃþªº¦W¦r©M¥ÑÃþ産¥Íªº´å¼Ðªº§O¦W¡C
½T©w´£¨Ñ¤@­Ó¤£¦P©óªí¦W¦rªº§O¦W¡AÁ×§K産¥Í²V¶Ã¡C ¦b³oùØ,¨Ï¥Î caCustomer °µÃþ¦W¡A cCustomer §@爲§O¦W¡C ¦pªG·QÅý³o­ÓÃþ¥Î©M¸ê®ÆÀô¹Ò¤@¼Ëªº¸ê®Æ·½¡AÀ³¸Ó¿ï¾Ü "Use DataEnvironment data source" ¡C ª`·N§A¥i¥H爲 CursorAdapter ³]¸m¤£¦Pªº¸ê®Æ·½, ¤¹³\§A¦b¤£¦PªºÃþ¤§¶¡¾ã¦X¸ê®Æ·½.( ¨Ò¦p¤@­ÓÃþ¨Ï¥ÎODBC¸ê®Æ·½¡A¥t¤@­ÓÃþ¨Ï¥ÎXML¸ê®Æ·½)

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G
­n©w¸qCursorAdapter ¦p¦óªð¦^¨Ó¦Û¸ê®Æ·½ªº¸ê®Æ,¨Ï¥Î³]­p¾¹¤¤ªºData Access ­¶¡C «öbuild«ö¶s±Ò°Ê¤@­Ó¹ï¸Ü¤è¶ô¡A¥i¥H¿ï¾Ü´å¼Ð¥]§tªºÄæ¦ì¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

¦b³o­Ó¨Ò¤l¤¤,¿ï¾ÜCustomersªí, µM«á¿ï¾ÜCustomers.*¡C ÂIÀ»¦V¥kªº½bÀY²¾°Ê¿ï¾Ü¶µ, µM«áÂIok¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

³o爲§A«Ø¥ß¤U¦CSQL»y¥y:
select CUSTOMERS.* from CUSTOMERS
¦pªG§A·Q²K¥[¿zÀ˵{¦¡,³s±µ, ©Î¨ä¥L±ø¥ó¨ì¬d¸ß,§A¥i¥H¦b¦Cªí®Ø¤¤ª½±µÁä¤J¡C ¦pªG§A·Q«Ø¥ß±a°Ñ¼Æªº¬d¸ß,¦³¤@¨Ç¿ï¶µ,¦b¥»¤å«á­±¤¶²Ð¡C ²{¦b, Åý§Ú­Ì²K¥[WHERE¤l¥y:
select CUSTOMERS.* from CUSTOMERS where
companyname like 'C%'
³oùØ¥i¥H¬Ý¥X·½ªí©M´å¼Ðªº¤£¦P¡A¦]爲¥u¦³¤Ö¼Æ°O¿ý²Å¦XWHERE¤l¥y¡C
¦b²Ä¤G­Ó½s¿è®Ø(schema)¤¤¤w¸g爲爲§A³Ð«Ø¤FÄæ¦ì¦Cªí¡C³q±`¦bÄ~Äò¥H«eªá´X¤ÀÄÁ¬Ý¬ÝÄæ¦ì¶¶§Ç¬O§_²Å¦X§Aªº²ßºD¬O¦³¦n³Bªº
¦b³o¤@­¶ªº¤U¥b³¡¤À¦³¸ê®Æ¥]³]¸m¹ï¸Ü¤è¶ô¡]data fetching¡^¡A¥Î¨Ó³]¸m«ç¼Ë³B²z»·ºÝ¸ê®Æ¥]¡A·í¥Îvfp§@爲¸ê®Æ·½ªº®É­Ô¡A³oùتº³]¸m¤£µo´§§@¥Î¡C¡]¦p¤W¹Ï¡^³oùاڭ̫O¯dÀq»{³]¸m¡Aµy«á¦AÁ¿­z¨ãÅé²Ó¸`¡C¦b¥»­¶ªº©³³¡ªþªñ¬O½w½Ä¼Ò¦¡³]©w, ¤¹³\§A³]¸m¥ô¦ó³QÃöÁpªºªí³æªº½w½Ä¼Ò¦¡¡C¦³¨â­Ó¿ï¶µ¡G¶}©ñ¦¡¦æ½w½Ä©M¶}©ñ¦¡ªí½w½Ä¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G

³q±`¡A§A¨Ï¥Î¶}©ñªºªí½w½Ä¼Ò¦¡¡A°£«D§A¦³¯S®í­n¨D¨Ï¥Î¦æ½w½Ä¼Ò¦¡¡C¦b³o­Ó¨Ò¤l¤¤³]¸m爲¶}©ñ¦¡ªºªí½w½Ä¡C³Ì«á¡A¡§break on error¡¨±±¨îCursorAdapterÃþ«ç¼Ë¨Ó³B²z¿ù»~¡CÀq»{³]¸m¬OÃþ¡]class¡^¦Û¦æ®·Àò¿ù»~¡A¨Ã¥B¤¹³\§A¥Îaerror()¨ç¼Æ®·Àò³o¨Ç¿ù»~¡C¿ï©w³o­Ó³]¸m¡ACursorAdapterÃþ¤º³¡¤£ºÞµo¥Í¤°麽¿ù»~¡Avfp³£·|¥X²{¿ù»~¸ê°T¡C¤]´N¬O»¡¡A§A»Ý­n¨Ï¥ÎON ERROR©R¥O©ÎªÌ¡¥Ãþ¡¦ªºERROR¨Æ¥ó¨Ó±Æ°£¤£»Ý­n³ø¿ùªº±¡ªp¡C³q±`±¡ªp¤U¤£¿ï³o¶µ³]¸m¡A¥H«Kµ{¦¡¯à³B²z¥ô¦óµo¥Íªº¨Ò¥~±¡ªp¡C
³Ì«á¤@­¶ (auto update) °t¸m¦p¦ó§ó·s·½ªí¡C¦b³q±`±¡ªp¤U¡A¿ï¾Ü¡§¦Û°Ê§ó·s¡]auto-update)¡¨©M¡§§ó·s©Ò¦³Äæ¦ì(update all fields)¡¨¡C

¦¹¥DÃD¬ÛÃö¹Ï¤ù¦p¤U¡G
³o±N¨ÏcursoradaperÃþ¹ï´å¼Ð¡]cursor¡^¤¤¸ê®Æªº¥ô¦ó§ïÅܦ۰ʫإ߾A·íªº§ó·s¡B´¡¤J¡B§R°£¾÷¨î¡CµM¦Ó¡A§A¥²¶·¿ï¾Ü´å¼Ð¤¤ªº¥DÃöÁäÄæ¦ì¡A¥H«K³o¨Ç¾÷¨î¡]§ó·s¡B§R°£¡B´¡¤J¡^°ß¤@ªºÃѧO·½ªí¤¤ªº°O¿ý¡C¦b¥»¨Ò¤¤¡ACustomerID¬OÃöÁäÄæ¦ì¡C¦]¦¹¡A»Ý­n¦b¨ä«e­±¤j¤W¡¥¹ï¸¹¡¦¡C¨ä¥Lªº³]¸m¼È®É«O¯d¹w³]­È¡C¨ãÅé³]¸m¿ìªk¦b¥»¤å«á­±Á¿­z¡C³]¸m§¹cursoradaper«á¡AÂIÀ»¡§ok¡¨«ö¶s¡A¦^¨ì¸ê®ÆÀô¹Ò³]¸m¡C¦¹®É¡A§AÀ³¸Ó¦b¥ªÃä¦Cªí®Ø¤¤¯à¬Ý¨ìcaCustomerÃþ, ¦b¥kÃä¬Ý¨ì²Ó¸`¡C¦pªG§A·Q§ó§ï³o­ÓÃþ¡A§A¥i¥HÀH®É¥Î¸ê®ÆÀô¹Ò¡¥builder¡¦§ó§ï¡A¿ï¾Ü»Ý­n§ó§ïªºCursorAdapter Ãþ¡AµM«áÂIÀ»builder«ö¶s¡C
¦s¨ú VFP ¸ê®Æ
¦¹®É¡A§A¥i¥H´ú¸Õ¸ê®ÆÀô¹Ò¡A¬Ý¬Ý¬O§_¯à¨ú¦^¦b CursorAdapter ªº«ü¥O¤¤¿z¿ïªº¸ê®Æ¡C ¨Ï¥Î©R¥Oµ¡¤á,¨Ò¥Ü DE Ãþ¦Ó¥B³ê°_ OpenTables ¤èªk:
lo = NewObject("deTest","Tests.vcx")
? lo.OpenTables()
BROWSE

¤@­Ó¯S®í±¡ªp¬O¡ACursorAdapterªº´å¼Ð³s±µ¨ì¨ä¥Lª«¥ó¡A¦pªG§A·´Ãa¤F«ü¦VCursorAdapterÃþªºª«¥ó¡A·|¥á¥¢´å¼Ð©M¨ä¤¤ªº°O¿ý¡C³o´N¬O»¡¡A§A¥²¶·½T«OCursorAdapterª«¥ó°Ñ¼Æ¦b§A¥´ºâ¦s¨úªºÃöÁp´å¼Ðªº½d³ò¤º
½s¿è VFP ¸ê®Æ
²{¦b, Åý§Ú­Ì¬Ý¬Ý¬O§_¯à°÷§ó·s´å¼Ð¡A¨Ã¥B§â§ó·s·Ç½T¦aµo°e¨ì·½ªí¡C¦b©R¥Oµ¡¤f´ú¸Õ¥H¤U©R¥O:
REPLACE contactname WITH 'My Name Here'
?TABLEUPDATE()
SELECT customers
BROWSE
ÂsÄýcustomers§O¦W,§A·|µo²{­×§ï¹Lªº°O¿ý¤w¸g§ó·s¨ì·½ªí¤¤¡C ¦pªG§A¦bµo°ereplace©R¥O¤§«e¨S¦³²¾°Ê°O¿ý«ü¼Ð,«È¤áID¤¤ 'CACTU' ©Ò¦bªº°O¿ý³Q­×§ï¡C ¤£ºÞ§A­×§ï­þ±ø°O¿ý, ³oÃÒ©ú CursorAdapter ¬O¯à°÷³Q§ó·s¡A¦Ó¥B§ó·s¯à°÷·Ç½T¦a³Qµo°e¨ì·½ªí¡C

Åý§Ú­Ì¥´¶}§A­è­è´ú¸Õªº¸ê®ÆÀô¹ÒÃþ¡A³o¤£¥u¬O¤@­Ó½m²ß¡X¥¦¬O¤@­Ó«Ü´Îªº¤èªk¾Ç²ß·í§A¨M©w¦b¸ê®ÆÀô¹Ò¥H¥~«Ø¥ß¦Û¤vªºÃþªº®É­Ô¡A¸Ó¦p¦ó¥¿½T¦a°t¸m¤@­Ó CursorAdapter Ãþ¡C

ÁöµM¸ê®ÆÀô¹Ò¦³¤@¨ÇÄݩʧïÅÜ©M¤@­Ó¤èªk, §Ú­Ì¹ê»Ú¤W¹ï¨º¨Ç§ïÅܤ£·P¿³½ì¡C¬Ý¤@¤U¤U©Ô²M³æ®Ø¤¤ªºÄݩʦCªí¡A¿ï¾Ü caCustomer Ãþ¡A¬Ý¬Ý«Ø¥ß CursorAdapter Ãþªº®É­Ô»Ý­n¶i¦æªº³]¸m¡C ªí 1 ·§­z³Qbuilder©M¨C­Ó PEM ©Ò°µ§ïÅÜ¡C
©Ò¦³ªºÄݩʥ]§t¦b "see Init" ,³q¹LINIT¤èªk¤¤ªº¥N½X¨Ó³]¸m³o¨ÇÄݩʡC ¨º¤@¬q¥N½XÅã¥Ü¦blist 1¤¤¡C
¦bbuilder³]¸m§¹¥H«á¡A¬Ý¬Ý¤@¨ÇÄݩʬO«ç¼Ë³]¸mªº¡A³o¬O³Ì¦nªº¾Ç²ß¤èªk¡C§A¥i¥H¦b³oùةΪ̳q¹Lbuilder§ïÅܳ]¸m­È¡CµM¦Ó¡A¦pªG¦b³oùاïÅܳ]¸m­È¡A§A»Ý­n«_¯}Ãa¤@¨Ç¥\¯àªº­·ÀI¡A¦]爲§A¦b³oùاïÅܪºÄݩʦ³¥i¯à¦bbuilderùؤ£·|µo¥Í§ïÅÜ¡C
¤£ºÞ«ç¼Ë,§A¯à¦b Init() ¥N½X¤¤¬Ý¨ì SelectCmd ÄݩʬO¦p¦ó敍­zªº, ¦P¼Ë¦b KeyFieldList ¡A UpdatableFieldList ©M UpdateNameList¤¤¤]¥i¥H¬Ý¨ì¡C ¯S§Oª`·N UpdateNameList ÄݩʡX³o­ÓÄݩʦC¥X´å¼Ðªº¨C¤@­ÓÄæ¦ì¥H¤Î·½ªí¤¤¹ïÀ³ªºÄæ¦ì(±aªí¦WºÙ)¡C
·í±qÀY³Ð«Ø§A¦Û¤vªº CursorAdapter Ãþªº®É­Ô¡A§A¥i¯à·Q¦b³o­Ó¦Cªí¤¤¬Ù²¤ªí¦W¦r¡C µM¦Ó¡A¦pªG¤£¨Ï¥Îºë½Tªº®æ¦¡¡A§Aªº§ó·s±N·|¥¢±Ñ, ¦ý¬O¨S¦³¿ù»~´£¥Ü¡C ¦b«á­±Á¿¤£³q¹Lbuilder«Ø¥ß¤@­ÓÃþªº®É­Ô§Ú±N¦A»¡³o¤@ÂI¡C
«e­±§Ú»¡¹L CursorAdapter¨Ï¥Î¥»¦aªº¸ê®Æ·½ªº®É­Ô , ¥»½è¤W¬O¤@­Ó´À¥N¤F¥»¦aµø¹Ï¡C¦pªG§A´¿¸g¥Î¹L¥»¦aµø¹Ï¡A§A¥i¥Hµo²{Ãþ¦üªº¦a¤è: ¥Í¦¨¤@­ÓSQL select»y¥y¡A©w¸q­þ¨ÇÄæ¦ì±N³Q§ó·s¡A³]¸mÃöÁäÄæ¦ì¡A³Ñ¤Uªº¨Æ±¡Åý VFP ¨Ó°µ¡C ¤@¥¹´å¼Ð¤¤¨ú¦^¸ê®Æ¡A¥i¥H¨Ï¥Î TableUpdate() µo°e§ó·s¨ì·½ªí¡A¦Ó¥B VFP ¦Û°Ê¦a«Ø¥ß¥²­nªºupdate,insert,delete»y¥y¡C
ÁÙ¬O¥H¤W­±ªº¨Ò¤l, ¨ú®øcCustomer §O¦W¤¤contactÄæ¦ì³Q´À´«ªº¸ê®Æ¡C³q¹LTableUpdate ¡A VFP ¦Û°Ê¦a産¥Í (¨Ã´£¥æ)¤U¦C§ó·s©R¥O¹Á¸Õ§ó·s:

UPDATE customers
SET CONTACTNAME=ccustomer.contactname
WHERE
CUSTOMERID=OLDVAL('customerid','ccustomer');
AND
CONTACTNAME=OLDVAL('contactname','ccustomer')
VFP ¯à°÷®Ú¾ÚCursorAdapterªºKeyFieldListÄݩʩM³¡¤ÀUpdateNameListÄݩʤ¤ªº­È産¥Íwhere¤l¥y¡C¥¦³q¹L¤l¥y°O¿ý¨º¨Ç¤w¸g³Q§ïÅܩβK¥[ªº°O¿ý¡A«OÃÒ§A¤£·|§ó·s¨º¨Ç§O¤H¤w¸g§ó·s¹Lªº°O¿ý¡Cª`·N¡A³o¬O¦]爲§Ú­Ì¦b¥¦ªºWhereType Äݩʤ¤«O¯d¹w³]­È "key fields and any modified fields."

¦b¥»¤å¤¤¥X²{table1,list1µ¥¡A¥i±¤§Ú·í®É¨S¤U¸ü¡A²{¦b¤w¸g§ä¤£¨ì¤F¡A¤£¹L¤£·|¹ï²z¸Ñ¥»¤å¦³¤°麽¼vÅT¡A¤U¦¸µo¡§cursoradapterÃþªº¿ù»~³B²z"

¿ù»~³B²z
©úÅ㪺¡A·í¥Î CursorAdapter §ó·s¸ê®Æ®É­Ô ,¨Ã¤£¯à§¹¥þ¦p§A©ÒÄ@¡C§Aª¾¹D,¦hºØ­ì¦]¥i¥H¾É­PTableUpdate §ó·s¥¢±Ñ, ¨Ò¦p§ó·s½Ä¬ð©Î°O¿ý¥[Âꥢ±Ñ¡C§A¥²¶·¹ï CursorAdapter Ãþ°µ¯S§O³B²z¨Óµo²{³o¨Ç°ÝÃD¶Ü? µª®×¬O,"µø±¡ªp¦Ó©w ."
§Ú­Ì¨Ó«Ø¥ß¤@­Ó²³æªº§ó·s°ÝÃD¡Gµ¹CursorAdapter¹Á¸Õ§ó·sªº¤@±ø°O¿ý¥[Âê¡C¦pªGÃþ³]­p¾¹¤´µM¬O¶}µÛªº,Ãö±¼¥¦¡CµM«á, ¹³«e­±°µ¹Lªº¤@¼Ë¡A¥Î NewObject ¨ç¼Æ啓°ÊdetestÃþ,¦Ó¥B啓°Ê OpenTables ¤èªk¡CÂsÄý´å¼Ð¥H«K§A¯à¬Ý¨ì¸ê®Æ,¦ý¬O¥ý¤£­n§ïÅÜ¥ô¦óªF¦è¡C
²{¦b¥´¶} VFP 8 ªº²Ä¤G­Ó¹ê¨Ò¡A³o¼Ë´N¯à°÷¥[Âê°O¿ý¡C ¦b©R¥Oµøµ¡¤¤¹B¦æ¤U¦C»y¥y¥[Âê§A±N¹Á¸Õ§ó·sªº°O¿ý:
OPEN DATABASE (HOME(2)+"Northwind\northwind.dbc")
USE customers
LOCATE FOR customerid = 'CACTU'
?RLOCK()
§AÀ³¸Ó¯àªð¦^.T.¡Aªí©ú°O¿ý½T¹ê³Q VFP ªº³o¤@­Ó¹ê¨Ò¥[Âê¡C
¦^¨ì VFP ªº²Ä¤@­Ó¹ê¨Ò¡A¦b©R¥Oµøµ¡¤¤¹B¦æ¤U­±ªº¥N½X:
REPLACE contactname WITH 'updated'
SET REPROCESS TO 2 SECONDS
?TABLEUPDATE()
¦b³oºØ±¡ªp, TableUpdate ªð¦^.F.,ªí²{°O¿ýÂêªý¤î§ó·s¦¨¥\¡C ¦pªG§A¥Î AERROR() ®·Àò¿ù»~¦Ó¥BÅã¥Ü¿ù»~µ²ªG, §A·|¬Ý¨ì¿ù»~¸ê°T "°O¿ý¨S¥[Âê"¡C ³o·N¨ýµÛ¦pªG§A¹ï³]¸m½w½Äªºªíª½±µ¾Þ§@¦Ó¤£¬O¤@­Ó´å¼Ð¡A§A¯à¥Î¦P¼Ëªº¿ìªk³B²z¿ù»~¡C
¤£©¯¦a¡A¤£¬O©Ò¦³ªº¹w´Á¿ù»~³£·|³o¼Ëªí²{¥X¨Ó¡C»Ý­n¯S§Oª`·Nªº¬O§ó·s½Ä¬ð,¤ñ¦p¤@­Ó¨Ï¥ÎªÌ¥ø¹ÏÂл\¨ä¥L¤H©Ò§@ªº­×§ï¡C·Q¬Ý¬Ý³oºØ¦æ爲ªºµ²ªG,¦b·í«eªº VFP ¹ê¨Ò¤¤(CursorAdapter ¥¿¦b¨Ï¥Î)¹B¦æ¤U­±ªº¥N½X¡G
?TABLEREVERT(.T.)
REPLACE contactname WITH 'client 1'
²{¦bÂàÅܦb¨ì²Ä¤G­Ó¨ÒÃҨåBµo¦æ¤U¦C«ü¥O:
CLOSE DATABASES all
OPEN DATABASE (HOME(2) + "Northwind\northwind.dbc")
USE customers
LOCATE FOR customerid = 'CACTU'
REPLACE contactname WITH 'client 2'
BROWSE
ªð¦^²Ä¤@­Ó¹ê¨Ò, ¹Á¸Õ¥Î TableUpdate µo°e§ó·s:
?TABLEUPDATE()
¦b³oºØ±¡ªp¡A TableUpdate ¿ù»~¦aªð¦^.T.,¨Ï§A¬Û«H§ó·s¦¨¥\¤F! µM¦Ó, ¨Æ¹ê¤W¨Ã¨S¦³¦¨¥\¡A¦Ó¥B³o¥i¥H³QCursorAdapterªºCursorRefresh() ¤èªkÃÒ©ú, ¥Î¤U¦C¥N½X:
?TABLEREVERT(.T.)
?lo.caCustomer.CursorRefresh()
CursorRefresh ¤èªk§i¶D CursorAdapter ¦A¹B¦æ SelectCmd ùتº»y¥y¡A¨Ã¥B¨ú¦^¨Ó¦Û·½ªíªº³Ì·s¸ê®Æ¡C ¹ïContactName Äæ¦ìªº´ú¸Õ»¡©ú CursorAdapter ®Ú¥»¨S§ó·sÄæ¦ì­È!
¸Ñ¨M³o¤@­Ó°ÝÃDªº³Ì²³æªº¤èªk­n§Q¥Î CursorAdapter ªº AfterUpdate ¤èªk¡C³o¤@­Ó¤èªk¦b TableUpdate µo°e«O¦s¨C±ø°O¿ýªº½Ð¨D«á³Q°õ¦æ¡Cª`·N³o­Ó¡¥¤èªk¡¦¥u¹ï·í«e°O¿ý¦³®Ä¡C ¦pªG°O¿ý¬O·sªº¡A©ÎªÌ°O¿ý¤w¸g³Q§R°£,·|±Ò°ÊAfterInsert ©Î AfterDelete ¤èªk¡C
AfterUpdate ¤èªk®·Àò¤@¨Ç°Ñ¼Æ, ¥]¬A³ÌªìªºÄæ¦ìª¬ºA,¬O§_³Q±j¨î§ó§ï, ©M§@爲§ó·sªº©R¥O¡C ³Ì«á¤@­Ó°Ñ¼Æ , lResult,¬O§Ú­Ì³o³¡¤À¥DÃD³Ì­«­nªº,¦]爲¥¦§i¶D§Ú­Ì§ó·s¹Lµ{¬O§_¦¨¥\¡C
¨Ï¥Îªº¥t¤@­Ó­«­n¨¤¦â¸Ñ¨M§ó·s½Ä¬ð°ÝÃDªº¬O¨t²ÎÅÜ¼Æ _tally, ¥¦§i¶D§Ú­Ì³Ì«á¤@¦¸¾Þ§@¼vÅT¤F¦h¤Ö°O¿ý¡C ¦]¦¹¡A¦pªG lResult ©ñ¦^¦¨¥\ªº, ¦ý¬O _tally¬O¹s,¨º麽»¡©ú¨S¦³°O¿ý³Q§ó·s¡A¨º麽§A¥i¥H§P©w³oºØ±¡ªp¬O¤@­Ó§ó·s½Ä¬ð¡C
²³æ»¡¡A¸Ñ¨M³o¤@­Ó°ÝÃDªºÂ²³æ¤èªk¬O§â¤U¦C¥N½X¥[¤J CursorAdapter Ãþªº AfterUpdate ¤èªk:
LPARAMETERS cFldState, lForce, nUpdateType, cUpdateInsertCmd, cDeleteCmd, lResult
IF lResult AND _TALLY = 0 THEN
ERROR 1585 && update conflict
ENDIF
¦³½ìªº¬O§A¦b¿Ã¹õ¤W¬Ý¤£¨ì¿ù»~¸ê°T;¿ù»~¸ê°T³Q TableUpdate ¡§­­¨î¦í¤F¡¨,³o´N­¢¨Ï§A¨Ï¥Î AError ¨ç¼Æ¤ÀªR§ó·s¥¢±Ñªº­ì¦]¡C¥X²{³o¼Ëªº²{¹³¬O¦]爲 BreakonError ÄݩʫO¯d¤F¹w³]­È ,¤]´N¬O¿ù»~¤£¤Þ°_µ{¦¡¤¤Â_¡C¦pªG§A§â³o­ÓÄݩʳ]爲¡§ture",¨º麽"§ó·s½Ä¬ð" ¿ù»~¸ê°T´N·|¥X²{,¦pªG§@¤F©w¸q,§AªºON ERROR±±¨î½X·|³Q¹B¦æ¡C
³o¤@­Ó§ó·s½Ä¬ð°ÝÃD¬O爲 CursorAdapter³]­pªº¡A¦]爲 VFP 8 ¨S¦³¦Û°Êµo²{³o­Ó°ÝÃD¤èªk¡C¦]¦¹¡A·í¤£¥Î¥»¦a¸ê®Æ·½ªº®É­Ô¡A³o­Ó¥N½X( ©Î¬Û¦üªº¥N½X)·|¥Î¦b§AªºCursorAdapterÃþ³]­p¤¤¡C


CursorAdapter with ODBC
²{¦b§A¤w¸g¦³¤F¤@©wªº°ò¦, Åý§Ú­ÌÄ~Äò¬Ý¬Ý·í«á»O¸ê®Æ®w¥Î SQL serverªº®É­Ô«ç¼Ë¶i¦æ³]¸m¡C§Ú­Ì±N±q¨Ï¥Î VFP ³q¹LODBC³s±µ SQL server¤Wªº Northwind ¸ê®Æ®w¶}©l¡C¦P¼Ë, Åý§Ú­Ì±qÀY«Ø¥ß CursorAdapter ¥H«K¥i¥H¬Ý¨£Ãþ»Ý­n³]¸mªº¦U­Ó¤è­±¡C
­º¥ý,¥Î¤U¦C«ü¥O¦bÃþ³]­p¾¹¤¤«Ø¥ß¤@­Ó·sÃþ:
CREATE CLASS caODBC OF tests as CursorAdapter
³oùػݭn³]¸mªº³Ì­«­nªºÄݩʬO DataSourceType ÄݩʡC ¦]爲§Ú­Ì·Q³q¹LODBC³s±µ SQL server,±N³o¤@Äݩʳ]¸m爲ODBC¡C·í¨Ï¥Î³oºØ³s±µ¤è¦¡ªº®É­Ô , DataSource Äݩʻݭn¦³¤@­Ó½T¤Áªº³s±µ±±¨î½X,¥i¥H¥Î SQLConnect ©Î SQLConnectString ¨ç¼Æ«Ø¥ß¡C ¦b¥ô¤@±¡ªp¡A³o¨Ç¥\¯àÀ³¸Ó¦b CursorAdapter Ãþªº Init ¤èªk¤¤¨Ï¥Î¤U¦C¥N½X:

LOCAL lcConnStr, lnConn
** string assumes trusted connection (integrated security)
lcConnStr = "Driver=SQL Server;Server=(local);DATABASE=Northwind"
lnConn = SQLSTRINGCONNECT(lcConnStr)
IF lnConn > 0 THEN
THIS.DATASOURCE = lnConn
ELSE
** unable to connect
ENDIF
³s±µ¦r¦ê°²©w§A¨Ï¥Î¥i«H¿àªºÃöÁp¨ì SQL server¡F¦pªG§A¨Ï¥Î¦w¥þªº³s±µ¨ì SQL server,§â "uid"= ©M "pwd"= ¦ê¥[¤J³s±µ±±¨î½X«ü©w¨Ï¥ÎªÌ¦WºÙ©M±K½X¡C ¥ô¦ó¤@ºØ±¡ªp¤U¡Aªð¦^ªº¬O³s±µ¬` , ©Î¿ù»~µo¥Í®Éªº§_©w­È¡C ³o¤@­Ó³s±µ¬`³Q«ü©w爲 DataSource ÄݩʥH«K CursorAdapter ª¾¹D¸Ó¨ì­þ¨½Án©ú¡C
¤U¤@­Ó¨BÆJ¬O«Ø¥ß SelectCmd ¥H«K CursorAdapter ª¾¹D»Ý­n±q¸ê®Æ·½¨ú¦^¤°麽¸ê®Æ¡CÁÙ¦³¤@­Ó³Ì¦nªº©ñ¸m¦a¤è¬O Init ¤èªk, ¦]爲ÄÝ©Êªí­­¨î¦r¦êªºªø«×¡C §â¤U¦C¥N½X¥[¤J Init ¤èªk¤¤,³]©w DataSource ÄݩʥN½X¤§«á, ¨ú¦^¤½¥q¦W¦r¤¤¥H "C" ¶}ÀYªº«È¤á¦Cªí:

This.SelectCmd = "SELECT " +
"CustomerID, CompanyName, ContactName, " +
"Address, City, Region, Country " +
"FROM Customers WHERE CompanyName LIKE 'C%'"
µM«á¡A§AÀ³¸Ó§i¶D CursorAdapter ³q¹L½Õ¥ÎCursorFill ¤èªk¶ñ¥R³QÃöÁpªº´å¼Ð¡C §A¥i¥H¬Ù²¤³o¤@­Ó½Õ¥Î¡A¨Ã¥B¤â°Ê±qÃþ¤§¥~½Õ¥Î, ©Î©ñ¦b Init ¤èªk¤¤¡A¥H«K¥¦¯à°÷¦Û°Ê¶ñ¥R´å¼Ð¡C¦bInit ¤èªk¤¤³]¸m SelectCmd ¤§«á¡A¥i¥H¥Î This.CursorFill()½Õ¥Î¡C

³Ì«á¡A§AÀ³¸Ó¦bÃþªºDestroy¤èªk¤¤¥[¤W¤@¨Ç¥N½X¡A¥H«K¦bª«¥ó±q°O¾ÐÅ餤ÄÀ©ñ¥H«á´î¤Ö¨ì¦øªA¾¹ªº³s±µ¡C ¨S¦³³o¨Ç¥N½Xªº¸Ü¡A¨C¤@­Ó·sªº¹ê¨Ò±N·|産¥Í¤@­Ó¨ì¦øªA¾¹ªº·s³s±µ, ¨Ã¥B¤£·|ÄÀ©ñ¥¦:

IF this.DataSource > 0 THEN
SQLDISCONNECT(this.DataSource)
ENDIF
Âǥѳo¨ÇÅܤơA§A¾Ö¦³¤@­Ó¹ê¥Îªº CursorAdapter Ãþ¡A¥¦¯à°÷¥Í¦¨¤@­Ó°ßŪªº´å¼Ð¡C¦b¤¹³\§ó·s¤§«e¡A´ú¸Õ¤@¤UÃþ¡A½T«O¥i¥Î¡A¨Ã¯à·Ç½T¨ú¦^¸ê®Æ¡C¥Î¤U¦C¥N½X´ú¸Õ:
lo = NEWOBJECT("caODBC","tests")
BROWSE
ª`·N¡A§A¤£»Ý­n¹³¸ê®ÆÀô¹Ò¨º¼Ë½Õ¥Î OpenTables ¤èªk¡C³o¬O¦]爲§A§â CursorFill ¤èªkª½±µ¥[¤J¤F Init ¤èªk,¨ÏÃþ¦b¹ê¨Ò¤Æ¤§«á¦Û°Ê¦a¶ñ¥R´å¼Ð¡C

Updating ODBC Data¡]§ó·sODBC¸ê®Æ¡^
爲¤F¨Ï³o­ÓÃþ¥i§ó·s,§A¥²¶·¥¿½T¦aµ¹Tables, KeyFieldList ¡A UpdatableFieldList ©M UpdateNameList Äݩʽá­È¡C ¨Ã¥B³]©w AllowInsert ¡A AllowUpdate ©M AllowDelete ÄÝ©Ê爲true, ½T©w¦Û°Ê§ó·s¯S¼x³Q±Ò°Ê¡C ¦A¤@¦¸±j½Õ¡A³Ì¦nªº¿ìªk¬O¦bInit ¤èªk¤¤¥Î¥N½X³]¸m³o¨ÇÄݩʡC Init ¤èªk¤@¨Ç¥N½X¦blist2 ¤¤¡C
¦bÃö³¬Ãþ³]­p¾¹¤§«e,§A¥i¯à·Q±N BufferModeOverride Äݩʴ«¦¨ "5",¡§¶}©ñªºªí½w½Ä¡¨¥H«K²¾°Ê°O¿ý«ü¼Ðªº®É­Ô , ¦Û°Ê§ó·s¤£µo¥Í¡C

´ú¸Õ CursorAdapter ªº§ó·s¯à¤O,§â¥¦§@爲¤@­Ó¹ê¨Ò,ÂsÄý´å¼Ð,§@¤@­Ó§ó§ï, µM«á´£¥æ TableUpdate¡C ½T©w©Ò§@ªº§ó§ï³Q¦^À³,½Õ¥Î CursorAdapter ªº CursorRefresh ¤èªk¡A¦AÂsÄý¤@¦¸¡C
³B²zODBC¿ù»~¡]Handling ODBC Errors¡^¶H¨Ï¥Î¥»¦a CursorAdapter¤@¼Ë ¡A¤j¦h¼Æªº¿ù»~³B²z¬O«ö·Ó "¶Ç²Îªº"¤èªk¡X´ú¸Õ TableUpdate ªð¦^ªº­È¡A¦pªG¥¢±Ñ¡A¨Ï¥Î AError ¨Ó§PÂ_­ì¦]¡C ¤£©¯ªº¬O¡A§ó·s½Ä¬ðªºÀË´ú¤]¬OODBC³s±µÃþ«¬ CursorAdapter ªº¤@­Ó°ÝÃD¡C

¥»¦a CursorAdapter ¿ù»~ªº¸Ñ¨M¿ìªk¬O¦b AfterUpdate ¤èªk¤¤³]¸m¿ù»~³B²z¥N½X, ¦ý³oºØ¤èªk¹ïODBC«¬ CursorAdapter ¬OµL®Äªº¡A¦]爲§ó·s¥¢±Ñªº®É­Ô¡A§Ú­Ì¤£¬O­n³B²zVFP¿ù»~,¦Ó¬OODBC¿ù»~¡C ¦]¦¹¡A³Ì¦nµª®×¬O¨Ï¥Î¤@­Ó¦sÀx¹Lµ{¡A©Î¦b§ó·s±±¨î½X¤¤¼W¥[¤@¨Ç¥N½Xµo°e¨ì¦øªA¾¹¡C

¦^·Q¤@¤U¡A爲¥»¦aªº CursorAdapter §ó·s¿ù»~ªº¸Ñ¨M¿ìªk¬OÀˬd _TALLY¡A¬Ý¬Ý¬O§_¦³°O¿ý³Q§ó·s¡C爲ODBC³s±µªº¸Ñ¨M¿ìªk»P¥»¦aCursorAdapter¬O¬Û¦üªº¡A¦ý¬O§Ú­Ì¤£¯à¨Ï¥Î _TALLY¡A¦]爲¦b»·ºÝ¸ê®ÆÀË´ú¤W¥¦¬O¤£¥i¾aªº¡C §Ú­Ì¥i¥H¨Ï¥ÎSQL serverªº@@Rowcount ¨t²Î¨ç¼Æ¨Ó§P©w°O¿ý¬O§_³Q§ó·s¡C

¦pªG§A­n¼g¤@­Ó T- SQL §å¶q§ó·s»y¥y¨Ó§ó·s¤@µ§°O¿ý,§AÀ³¸Ó¶H¤U­±³o¼Ë¼g:
--@custID and @oldContact set by earlier code or parameters
UPDATE customers
SET ContactName = @newContact
WHERE CustomerID = @custID
AND ContactName = @oldContact
IF @@ROWCOUNT = 0
RAISERROR('Update failed.',16,1)
RaisError T- SQL ¨ç¼Æ¨Ï VFP ±µ¦¬¤@­ÓODBC¿ù»~ (1526 ¸¹), ¦b²Ä¤@­Ó°Ñ¼Æùؼg¿ù»~¸ê°T.(¥t¥~¤G­Ó°Ñ¼Æ«ü¥XÄY­«©M¿ù»~ªºª¬ºA) ¦b³oºØ±¡ªp¤U¡A ·í@@Rowcount=0ªº®É­ÔRaisError ³Q½Õ¥Î, ªí©ú¦­¥ýªº T- SQL »y¥y¨S¼vÅT¥ô¦óªº°O¿ý¡C

©Ò¦³°Q½×ªº³o¤@¨Çªí©ú§A¥i¥H¨Ï¥Î CursorAdapter ªº BeforeUpdate ¤èªk¨Ó´y­zµo°e¨ì¦øªA¾¹¥Î¨Ó§ó·sªº»y¥y¡C BeforeUpdate ¤èªk±µ¨ü¤­­Ó°Ñ¼Æ, ¦³½ìªº¬O³Ì«áªº¤G­Ó (cUpdateInsertCmd ©M cDeleteCmd) «Ø¥ß¤FÃöÁp¡]ª`¡G­ì¤åthe last two (cUpdateInsertCmd and cDeleteCmd) are interesting in that they are passed by reference. ¡^¡C ¦b¥¦­Ì³Q°e¥h¸ê®Æ·½¤§«e , ³o¤¹³\§A­×§ï«ü¥O¡C

¦b§Ú­Ìªº¨Ò¤l¤¤¡A§Ú­Ì¨Ï¥Î³o¤@­Ó¤èªk¼W¥[¤@­Ó¹ï@@Rowcountªº´ú¸ÕµM«á½Õ¥Î RaisError ¡C§â¤U¦C¥N½X¼g¤J BeforeUpdate :
LPARAMETERS cFldState, lForce, nUpdateType,
cUpdateInsertCmd, cDeleteCmd
IF nUpdateType = 1 THEN
cUpdateInsertCmd = cUpdateInsertCmd +
" if @@ROWCOUNT = 0 "+
"RAISERROR('Update Failed due to update " +
"conflict.',16,1)"
ENDIF
²{¦b¡A爲µo°e¨ì«á»O¸ê®Æ®wªº¨C¤@¦æ°O¿ý¡A¥Î³o¬q¥N½X´ú¸Õ¦æ¬O§_³Q§ó·s¡C ¦pªG¨S§ó·s¡A VFP ±N·|±µ¦¬¨ì¿ù»~,TableUpdate ±N·|¥¢±Ñ¡A¦Ó¥B AError ±N·|Åã¥Ü1526¸¹¿ù»~¡A¨ÃÅã¥Ü¹w³]ªº¿ù»~¸ê°T¡C

¦s¦b¤G­Óªº°ÝÃD¡C ­º¥ý¡A³o¬O¯S§O爲 SQL server³]¸mªº¡F¹ï¨ä¥LªºODBC¸ê®Æ·½ ( ¤ñ¦pORACLE) ¡A³o¤@¬q¥N½XµL®Ä¡C ¨ä¦¸¡A³o­Ó¿ù»~¸ê°T¬O«ü¤@Ãþ¿ù»~¡AÁ`¬O産¥Í¬Û¦Pªº VFP ¿ù»~¸¹, ¦Ó¥B¦b VFP ¤¤«Ø¥ß¥¿½Tªº¿ù»~³B²z±±¨î½X¦³¤@ÂI§xÃø¡C³o¤@­Ó°ÝÃD¥i¥H³q¹L¦bSQL SERVER¦øªA¾¹¤W«Ø¥ß³q¥Îªº¿ù»~¸ê°T¡A¨C±ø¸ê°T¹ïÀ³µÛ¦Û¤vªº°ß¤@¿ù»~¸¹½X¡C

¥t¥~¤@­Ó§ó¦nªº¸Ñ¨M¤èªk¬O¨Ï¥Î¦sÀx¹Lµ{¨Ó°õ¦æ§ó·s¡A¥N´À¥ÎVFP«Ø¥ß¤@­Ó¬d¸ß¡C ·íµM¡A±Ä¥Î¦sÀx¹Lµ{ªº¤£§Q¦]¯À¬O¤£¯à¨Ï¥ÎVFP ªº¦Û°Ê§ó·s±±¨î½X¨Ó§ó·s¸ê®Æ¡C

°Ñ¼Æ¤Æ³]¸m Parameterization
³q¹L¾Ç²ß¡A§A¤w¸gª¾¹D¦p¦ó爲 CursorAdapter Ãþªº¤èªk¡BÄݩʲK¥[©R¥O¡C °ò¥»¤W¡A¦bÃþ¤¤¨Ï¥Îªº¨C­Ó¨Æ¥ó¡]event)³£¦³¤@²Õbefore©Mafter¤èªk, ¤ñ¦p BeforeUpdate ©M AfterUpdate ¡CµM¦Ó,¨S¦³ BeforeSelect ©Î AfterSelect¡Ð´À¥N¥¦­Ì¥s°µ BeforeCursorFill ©M AfterCursorFill,¦]爲´å¼Ð¬O¥Î SelectCmd ªºµ²ªG¨Ó¶ñ¥Rªº¡C
BeforeCursorFill ¤èªk±µ¨ü¤T­Ó°Ñ¼Æ, ¦Ó¥Bªð¦^ Boolean ­È¡C ²Ä¤@­Ó°Ñ¼Æ , lUseCursorSchema, 敍­z CursorSchema ÄݩʬO§_±±¨î´å¼Ðªºµ²ºc¡C ²Ä¤G­Ó°Ñ¼Æ , lNoDataOnLoad,»Pµø¹Ïªº NODATA ¤l¥yÃþ¦ü,¥u¨ú¦^ªíµ²ºc¡A¦ý¬O¨S¦³±q¸ê®Æ·½¨ú¦^¸ê®Æ¡C

¹ï©ó²{¦bªº°Q½× , ²Ä¤T°Ñ¼Æ , cSelectCmd,¬O³Ì¦³·N«äªº¡C §Ú­Ì¤w¸g´£¨ì¹L¥¦ (¶H BeforeUpdate ªº cUpdateInsertCmd °Ñ¼Æ) ¡A¥ý¨Ï¥Î SelectCmd ªº·í«e³]¸m¡CµM¦Ó¡A¦pªG§A§ïÅܳo¤@­Ó°Ñ¼Æªº­È,¥¦¤£§ïÅÜ SelectCmd Äݩʪº­È¡F¨ú¦Ó¥N¤§ªº¬O¡A¥¦ªº­È§ï爲³Q¶Çµ¹¸ê®Æ·½ªº»y¥y ¡C

Á|¨Ò¨Ó»¡, °²¦p§A¤w¸g§â CursorAdapter ª«¥óªº SelectCmd ³]©w爲¤U¦C¥N½X:

SELECT CustomerID, CompanyName, ContactName, City,
Region, Country FROM Customers
¦b©I¥s CursorAdapter ªº CursorFill ¤èªk¤§«e¡A BeforeCursorFill ¤èªkªº cSelectCmd °Ñ¼Æ·|¥]§t³o­Ó»y¥y¡C °²¦p§A¦b³o¤@­Ó¤èªk¤¤¥Î¤U¦C¥N½X:
cSelectCmd = cSelectCmd +
" WHERE CompanyName LIKE '" +
this.cCompanyName + "%'"
³o´N¾É­P¹ê»Úªºselect©R¥OÁ`¬O¥]§t¦p¤W­±¥N½X´y­zªºwhere¤l¥y©M this.cCompanyName¡]¦Û©w¸qÄݩʡ^ ªº·í«e­È.¦]爲¥¦¤£§ïÅÜ SelectCmd ªºªì©l­È, §A¤£¥²¥Î¥ô¦ó¯S§Oªº¥N½X¨Ó½T©w¦bselect©R¥O¤¤¬O§_¥]§t¨â­Ówhere¤l¥y¡C

°Ñ¼Æ³]¸m²Ä¤G³¡¤À
¦pªG§A¥H«e¥Î¹Lµø¹Ï¡A©Î SQL pass through,¨º麽§A¥i¯à¼ô±x¦b°Ñ¼Æ«e¨Ï¥Î "?" ¦r¤¸¡C ³o¤@­Ó¥Îªk¤]¾A¥Î©ó CursorAdapter ¡C ¤U­±ªº¥N½X¨Ò¤l§i¶D§A¦p¦ó¦b CursorAdapter ªº SelectCmd Äݩʤ¤¨Ï¥Î°Ñ¼Æ:

This.SelectCmd = "SELECT * FROM Customers " +
" WHERE CompanyName like ?lcMyVar "
lcMyVar = 'C%'
This.CursorFill()
³Ì­nºòªº¬O½T©wÅÜ¼Æ "lcMyVar" ¦b CursorFill ¤èªk³Q½Ð¨D¤§«e³Q©w¸q¡C§_«hªº¸Ü¡AVFP·|´£¥Ü§ä¤£¨ì­È,¨Ï¥ÎªÌ·|µL©Ò¾A±q¡C

§A¥i¥H¨Ï¥Î CursorAdapter ªºÄݩʧ@爲°Ñ¼Æ,¥Î¨Ó´À¥N¥»¦aªºÅܼơC³o¼Ë°µ¦³³o¼ËªºÀuÂI¡G¥u­nª«¥ó¦s¦b¡AÄݩʤ]·|¦s¦b¡A¦Ó¥B§A¥i¥H³q¹L¨Ï¥Îaccess/assign¤èªk¨Ó½T©w¤À°tªº­È²Å¦X³W«h¡C

¨Ï¥Î¦sÀx¹Lµ{
¦b¤W­±»¡¹L, ¨Ï¥ÎÀx¦s¹Lµ{¬O¤@­Ó¬ð¯}¿ù»~³B²z­­¨îªº¦n¿ìªk¡CÅý§Ú­Ì³v¨B±´¨s¦bODBC CursorAdapter¤¤¨Ï¥Î¦sÀx¹Lµ{ªº¤èªk¡C³o¼Ë§Ú­Ì´N¯à·Pı¥X¤â°Ê³B²z CursorAdapter Ãþªº§ó·s¿ù»~¬O¦h麽½ÆÂø¡C
³o¤@¬q¬OÃö©ó³q¹L½Õ¥Î¸ê®Æ·½ªº¦sÀx¹Lµ{¨Ó¥N´À¦Û°Ê°õ¦æªºupdate¡Binsert©Mdelete©R¥O¡C ³o·N¨ýµÛ§A¥²¶·³B²z UpdateCmd ¡A InsertCmd ©M DeleteCmd ÄÝ©Ê, ¦Ó¥B°²³] SQL server¤Wªº Northwind ¸ê®Æ®w¤w¸g«Ø¥ß¦sÀx¹Lµ{¨Ó´£¨Ñ³o¨Ç¥\¯à¡C

¨Ò¤l, Åý§Ú­Ì¬Ý¤@¬Ý¤@­Ó²³æ¦sÀx¹Lµ{ªº§¹¾ã¥N½X¡A§A¥i¥H¥Î¥¦§ó·s Northwind ¸ê®Æ®wªºcustomerªíªº ContactName Äæ¦ì:

--T-SQL code, not VFP
CREATE PROCEDURE UpdateCustomerContact (
@CustomerID nchar (5),
@ContactName nvarchar (30),
@oldContact nvarchar (30)
)
AS
IF @CustomeriD IS NULL
RAISERROR('CustomerID is a required parameter',16,1)
ELSE
UPDATE Customers
SET ContactName = @contactName
WHERE CustomerID = @customerID
AND ContactName = @oldContact
爲¤F¸`¬ùªÅ¶¡,³o¤@­Ó¦sÀx¹Lµ{¨S¦³¥]§t¥þ³¡ªº¿ù»~³B²z¥N½X¡C ¤£ºÞ³o­Ó,¤w¸g¦³¨¬°÷ªº¥N½X¨Ó»¡©ú«ç¼Ë¦b CursorAdapter Ãþ¤¤°õ¦æ§ó·s¡C

©¯¹B¦a, «Ø¥ß UpdateCustomerContact ¦sÀx¹Lµ{§@爲§ó·s©R¥O¡A¥i¥H¨ú¥N BeforeUpdate ¤èªk¡A¥Î¤U­±ªº¥N½X:
LPARAMETERS cFldState, lForce, nUpdateType,
cUpdateInsertCmd, cDeleteCmd
cUpdateInsertCmd =
"EXECUTE UpdateCustomerContact '" +
EVALUATE(this.Alias+".CustomerID") + "','" +;
ALLTRIM(EVALUATE(this.Alias+'.ContactName'))+
"','" +
OLDVAL('contactname',this.Alias)+"'"
³oùØ,¥N½X©ñ¦b cUpdateInsertCmd °Ñ¼ÆùØ,Âл\¤FÀq»{ªºupdate©R¥O¡C§Ú¨Ï¥Î¤Fevaluate¨ç¼Æ¡A¬O爲¤Fcursorªº¦W¦r¬O°ÊºAªº¡A»¡©úcursorªº¦W¦r¥i¥H«Ü®e©ö³Q§ïÅÜ¡A¦ý¬O¥N½X¤£ÅÜ¡CÁÙ¦³¡A§Ú¨Ï¥Î¤FOLDVAL ¨ç¼Æ¨ú¦^ ContactName Äæ¦ì³Q­×§ï«eªº­È¡C¦pªG¦b¦sÀx¹Lµ{ªºwhere¤l¥yùػݭnªº¸ê®Æ¡A¨º麽³o­Ó¨ç¼Æ¬O¥²»Ýªº¡C³o¦³ÂI¹³¦Û°Ê産¥Íupdateªº±¡ªp¡C
°O¦í¡A¦b°O¿ý³Q¹ê»Ú§ó·s¤§«e ,³q¹LTableUpdate¦Û°Ê©I¥s BeforeUpdate ¤èªk¡C ¦]¦¹, µL½×UpdateCmd·í«eªº­È¬O¤°麽¡A³o­Ó¤èªkµ{¦¡¡]«üUpdateCmd¡^³Q¸T¥Î¡A¦Ó¥BÁ`¬O¨Ï¥Î¦sÀx¹Lµ{¡C

ª`·N¡A§A¤]¥i¥H¨Ï¥Î¤w¸g°Q½×¹Lªº°Ñ¼Æ³]¸m¤èªk¡A¨Ï¥Î BeforeUpdate ¤èªk¡C ³o´N­n¨D§A爲 CursorAdapter ´£¨Ñ UpdateCmd³]¸m,¦ý¬O, ¤£­n¦b°Ñ¼ÆùإΩT©wªº¥N½X¡A­n¥ÎÅܼƩΪÌÄݩʡA¨Ã¦b¥¦­Ì«e­±¥[¤W¡§¡H¡¨¡C

¦b³oùػݭnª`·Nªº­«­nªº¤@ÂI¬O cUpdateInsertCmd( ©Îª«¥óªº UpdateCmdÄÝ©Ê) ¤£¯àªð¦^¥ô¦ó­È¡C ¶i¤@¨B»¡¡A¦pªG§A±q¦sÀx¹Lµ{ªð¦^¤@­Ó­È¡A¥¦´N¨S¦³¦a¤è "¥h" ¡A¨º麽³o­Ó­È´N·|¥Ã»·¥á¥¢¡C¦]¦¹,¦b¦sÀx¹Lµ{¤¤²K¥[¤@­ÓRaisError©I¥s¡A¥H«K¦b§ó·s¹Lµ{¤¤µo¥Í¥ô¦ó¿ù»~( ¨Ò¦p¤£¥¿½Tªº°Ñ¼Æ©Î¤@­Ó§ó·s½Ä¬ð) ªº®É­Ô¡A§Aªº¥N½X¯à°÷§@¥X¤ÏÀ³¡A³o¼Ë°µ¬O«D±`­«­nªº¡C§A¥i¥H³q¹L´ú¸Õ TableUpdate ªð¦^­È¨Ó®·Àò¿ù»~ ,©ÎªÌ¥Î AError ¤èªk, µM«á¤ÀªR¿ù»~¡C

¬Û¦üªº¥N½X¤]À³¸Ó¼g¶i BeforeInsert ©M BeforeDelete ¤èªk,¥H«K¥¦­Ì¤]½Õ¥Î¦sÀx¹Lµ{¡A¦Ó¤£¬O½Õ¥Î³]¸m¦nªº¡§¬d¸ß¡¨¡C 爲¤F¸`¬ùªÅ¶¡¡A§Ú±N¯d¤U¥N½X·í°µ "ŪªÌªº½m²ß."

CursorAdapter with OLE DB
§Ú­Ìªº¤U¤@­Ó¥ô°È¬O¬Ý¬Ý¦p¦ó³q¹L CursorAdapter Ãþ¨Ï¥ÎOLE DB¡]ª«¥ó³s±µ»P´O¤J¡^, ¨Ã¥B§â¥¦¦P§Ú­Ì¥Î¹Lªºnative©MODBC§@¤@¤ñ¸û¡COLE DB§Þ³N¤ñODBC¦³§ó¦hªº³B²z¯à¤O, ¦Ó¥B¯à°÷³s±µªº¸ê®Æ·½Ãþ«¬¤ñODBC¦h¡C CursorAdapter ³q¹L´O¤JADOª«¥ó¨Ï¥ÎOLE DB¡A³o¬OOLE DB§Þ³N¼Ð·Çªº COM «Ê¸Ë¡C VFP ·|¦Û°Ê¦a§âADO°O¿ý¶° Âà´«¦¨¤@­Ó VFP ´å¼Ð, ¥H¤Î³B²z§ó·s, ¥¿¦p¦b¦­¥ýªº¨Ò¤l¤¤Á¿¨ìªº¤@¼Ë¡C

²Ä¤@¥ó­n°µªº¨Æ,·íµMÁÙ¬O«Ø¥ß¤@­Ó·sªº CursorAdapter Ãþ¡A§Ú­Ì¥Î¥N½X«Ø¥ß¤@­Ó¡C

¶}©l«Ø¥ß¤@­Ó·sªºµ{¦¡¡A¨ú¦W¦r caADO.prg, §â¤U¦C¥N½X²K¥[¶i¥h:

PUBLIC goCAADO as CursorAdapter
goCAADO = CREATEOBJECT('caADO')
BROWSE
DEFINE CLASS caADO AS CursorAdapter
oConn = NULL
oRS = NULL
Alias = "cCustADO"
DataSourceType = "ADO"
SelectCmd = "SELECT " +
"CustomerID, CompanyName, ContactName, "+;
"ContactTitle, Address, City, Country "+;
"FROM Customers WHERE Customerid LIKE 'C%'"
FUNCTION Init()
This.DataSource = this.oRS
This.oRS.ActiveConnection = this.oConn
This.CursorFill()
ENDFUNC
ENDDEFINE
¦b³o¬q¥N½X¤¤¡A§Ú­Ì±N DataSourceType ³]爲ADO¦Ó¥B§â§Ú­Ì¹ïCustomersªº¬d¸ß¥[¤J SelectCmd ¡C ·í DataSourceType ¬OADOªº®É­Ô, DataSource Äݩʥ²¶·¥]§t¦³®Äªº RecordSet ©Î©R¥Oª«¥ó, ³o¨Ì¿à©ó§A¦p¦ó¨Ï¥Î CursorAdapter¡C ¦pªG§A¤£¨Ï¥Î°Ñ¼Æ¤Æ¬d¸ß (´N¶H«e­±¨Ò¤l¤¤Á¿¨ìªº¥Î "?")¨º麽§A¥i¥H¥Î°O¿ý¶°( RecordSet )¡F§_«h¡A§A¥²¶·¨Ï¥Î©R¥Oª«¥ó,¦]爲ADO¤w¸g¥N´À¤F°Ñ¼Æ¿ï¾Ü¡C §Aªº¬d¸ß¤¤ªº¥ô¦ó°Ñ¼Æ¦b©R¥Oª«¥ó¤¤¦Û°Ê¦a³Q³B²z¡C

¦b³oºØ±¡ªp¤U¡A§Ú­Ì¨Ï¥Î RecordSet ª«¥ó , ¦ý¬OÀ³¸Óª`·N§Ú­Ì¥²¶·´£¨Ñ¤@­Ó¡§³s±µ¡¨ª«¥ó¡C ¦b³o¨âºØ±¡§Î¤¤¡A§Ú¨Ï¥ÎAccess¤èªk«Ø¥ß¤FÃö©ó³o¨Çª«¥óªº°Ñ¦Ò¡C list3 ¤¤¬OAccess¤èªkªº¥N½X¡C

¨â­ÓAccess¤èªk­º¥ýÀˬdª«¥ó¬O§_¤w¸g³Q«Ø¥ß¡C ¦pªG¨S¦³¡A¨º麽´NÄ~Äò³Ð«Øª«¥ó¡C¦b¨Ï¥Î RecordSet ªº±¡§Î¡A§A¥u»Ý­n«Ø¥ßª«¥ó,³Ñ¤Uªº¥Ñ CursorAdapter ¨Ó°µ¡C ¥Î¡§³s±µ¡¨ª«¥óªº±¡ªp¤U¡A §A¥²¶·´£¨Ñ³s±µ¦r¦ê¡]³s±µ±±¨î½X¡^¨Ã¥B¥´¶}³s±µ¡A¦]爲CursorAdapter ¤£爲§A¥´¶}³s±µ¡C³o¬O¦]爲¡§³s±µ¡¨¤£¬O CursorAdapter ªº¤@­ÓÄÝ©Ê, ¦Ó¬O RecordSet ª«¥óªº¤@­ÓÄݩʡC
¤U¤@¦¸µo¡G¥ÎOLE DB§ó·s

¥ÎOLE DB§ó·s
¦pªG¤£¥t¥~³]©w´X­ÓÄݩʡA³o麽²³æªº CursorAdapter ¬O¨S¦³§ó·s¯à¤Oªº¡C §â¤U­±ªº¥N½X©ñ¦b©w¸qÃþ(define)ªº¥N½X¤¤¡A¦binit¤èªk¤§«e¹B¦æ¡A±N·|¤¹³\¦Û°Ê§ó·s:

KeyFieldList = "CustomerID"
UpdatableFieldList =
"CompanyName, ContactName, ContactTitle, "+
"Address, City, Country"
UpdateNameList =
"CustomerID Customers.CustomerID, " +
"CompanyName Customers.CompanyName, " +
"ContactName Customers.ContactName, "+;
"ContactTitle Customers.ContactTitle, " +
"Address Customers.Address, "+;
"City Customers.City, Country Customers.Country"
Tables = "Customers"
µM¦Ó¡A RecordSet ·|«Ø¥ß¥¦ªºÀq»{ªº CursorLocation ©M CursorType ÄݩʡC ¦pªG¤£§ïÅܳo¨ÇÄݩʳ]¸m¡A RecordSet ³Ìªì¬O°ßŪªº,¦]¦¹¡A§A»Ý­n«ö¥H¤U¤èªk­×¥¿ oRS_Access ¤èªk:
FUNCTION oRS_Access() as ADODB.RecordSet
LOCAL loRS as ADODB.RecordSet
IF VARTYPE(this.oRS)<>"O" THEN
this.oRS = NULL
loRS = NEWOBJECT("ADODB.Recordset")
IF VARTYPE(loRS)="O" THEN
loRS.CursorType= 3 && adOpenStatic
loRS.CursorLocation = 3 && adUseClient
loRS.LockType= 3 && adLockOptimistic
this.oRS = loRS
ENDIF
ENDIF
RETURN this.oRS
ENDFUNC
爲 RecordSet ¥[¤W³o¨Ç¥N½X¥H«á¡A CursorAdapter ´N¯à³B²z¦Û°Ê§ó·s¤F¡C
¤U¤@¦¸µocursoradapter with XML

CursorAdapter with XML
³Ì«á, Åý§Ú­Ì«Ø¥ß¨Ï¥ÎXML§@爲¸ê®Æ·½ªº CursorAdapter¡C ³o¤@¸`«Ü¦³½ì,¦]爲XML¤å¥»¤£¹³³q±`ªº¸ê®Æ·½¡C ¦P¼Ë¡A·í¸ê®Æ·½³]¸m爲XMLªº®É­Ô¡A CursorAdapter ¤£·|¦Û°Ê«Ø¥ß SQL §ó·s, ´¡¤J©Î§R°£©R¥O¡C¦]¦¹¡A³oºØÃþ«¬ªº CursorAdapter »Ý­n¤j¶qªº¥N½X±µ¦¬©M§ó·s¸ê®Æ¡C

¦b³o¤@­Ó¨Ò¤l¤¤¡A§Ú±N¨Ï¥Î SQL server 2000 ªº SQLXML ´£¨ÑXML¤å¥»¡C ¦P®É¡A¦]爲SQLXML¤ä´©³q¹LXML§ó·s¡A§Ú­Ì±Nªá¤@ÂI®É¶¡¼g¥²­nªº¥N½X¨Ó°õ¦æ§ó·s¡C °²³]§A¤w¸g°t¸m¤FSQLXML¡A¤¹³\HTTP¸ê®Æ¦s¨úNorthwind ¸ê®Æ®w,¦Ó¥B¤¹³\¥Î UpdateGrams ¹ï¸ê®Æ®w¶i¦æ§ó·s¡C

¦b³oùØ¡A§Ú¦b IIS ¤W­±³]¸m¨Ï¥Î¤@­Ó³QºÙ爲 "nwind" ªºµêÀÀ¥Ø¿ý¦s©ñ HTTP ¸ê®Æ¡C ¦]¦¹¡A§Úªº¥þ³¡¨Ò¤l±N·|¥]§t³o­Óºô§}¡G
http://localhost/nwind¡A¸g¥Ñ IIS ¦s¨ú SQLXML¡C
Åý§Ú­Ì¶}©l«Ø¥ß¤@­Ó·sªºµ{¦¡¡Aµ{¦¡¦W¦r爲caXML.prg¡A¥Î¤U¦C¥N½X¡]³Ð«Ø¤@­ÓÃþ¡^:
PUBLIC oCAXML as CursorAdapter
SET MULTILOCKS ON && need for table buffering
oCAXML = CREATEOBJECT('xcXML')
BROWSE NOWAIT
DEFINE CLASS xcXML AS CursorAdapter
DataSourceType = "XML"
Alias = "xmlCursor"
UpdateCmdDataSourceType = "XML"
InsertCmdDataSourceType = "XML"
DeleteCmdDataSourceType = "XML"
BufferModeOverride = 5
*custom properties
oXMLHTTP = NULL
oXMLDOM = NULL
cServer = "localhost"
cVDir = "nwind"
ENDDEFINE
¤£¦P©ó³q±`ªº DataSourceType ©MAlias¡]§O¦W¡^Äݩʳ]¸m¡A³o¬O§Ú­Ì²Ä¤@¦¸¬Ý¨£ xxxCmdDataSourceType ÄݩʡC ¦]爲³o¬O¤@­ÓXMLÃþ«¬ªº CursorAdapter,¦pªG§A·QÅý¥¦¥Î¨Ó§ó·s·½¸ê®Æ¡A³o¨ÇÄݩʴN¥²¶·¶i¦æ³]¸m ¡C±ÀÂ˦b³o­ÓÃþ¤¤¨Ï¥Î oXMLHTTP ©M oXMLDOM ÄݩʡA±N·|¦b¤U­±°µ¸Ô²Ó»¡©ú¡C

±µ¦¬XML¸ê®Æ
¦b¦Ò¼{ CursorAdapter ªº§ó·s¯à¤O¤§«e,§Ú­Ì¥ý¬ã¨s«ç¼Ë±qSQLXML ¦øªA¾¹±µ¦¬¤å¥»¡C ­º¥ý,¤@­Ó²³æªºselect©R¥O¤£¯à¤u§@,§Ú­Ì¥²¶·«Ø¥ß³q¥Îªº SelectCmd ¡C ³o¦b Init ¤èªk¤¤«Ü®e©ö°µ¨ì,¦P®É¡A¦bINIT¤¤½Õ¥Î CursorFill ¤èªk,¦p¥H¤U¥N½X:
FUNCTION INIT() as Boolean
LOCAL llRetVal, lcMsg, laErr[1]
this.SelectCmd = "this.GetXml()"
llRetVal = THIS.CursorFill()
IF NOT llRetVal THEN
AERROR(laErr)
lcMsg = "Cursor was not filled!"
IF NOT EMPTY(laErr[2]) THEN
lcMsg = lcMsg + CHR(13) + laErr[2]
ENDIF
MESSAGEBOX(lcMsg,16,"XMLCursorAdapter Test")
ENDIF
RETURN llRetVal
ENDFUNC
³o¤@¬q¥N½X«Ø¥ß SelectCmd §@爲¥»¦a¥Îªº¤èªk,¥N´À SQL ©R¥O¡C ¥H«eªº¨Ò¤l¤¤¨S¦³³o¼Ë°µ¹L,¹ï¥ô¦ó CursorAdapter Ãþ,¤£ºÞ¤°麽Ãþ«¬,³£¬O¦Xªkªº¡CµM¦Ó¡A·í§A¨Ï¥Î¤@­Ó¥»¦aªº¤èªk§@爲 SelectCmd ªº®É­Ô,§A¥²¶·¤]´£¨Ñ¥N½X¥Î¨Ó§ó·s,´¡¤J©M§R°£, ¦]爲¦pªG¤£¬O¤@±øSQL»y¥yªº¸Ü¡A VFP ¬O¤£·|¦Û°Ê³B²zªº¡C
·í§Ú­Ì¦b Init() ¤¤¨Ï¥Î CursorFill ªº®É­Ô,GetXML ¤èªk³Q½Õ¥Î¡C ¸ê®Æ·½³]©w爲XMLªº®É­Ô,GetXML ¤èªk¥²¶·ªð¦^¥u¥]§t¤@­Óªíªº³Ì²×¤å¥»¡C ¦pªG¥¦¥]§t¦h­Óªí,§A·|±o¨ì®Æ·Q¤£¨ìªºµ²ªG¡C GetXML ¤èªk¦blist4 ¤¤¦C¥Ü¡C

GetXML¶}©l©ó´£¥æ¤@­Ó MSXML2.XMLHTTP COM ª«¥ó¡C ³o­Óª«¥ó³B²z©Ò¦³ HTTP ³q«H,¥]¬Aµo°e½Ð¨D¨ì¦øªA¾¹¨Ã¥Bªð¦^µ²ªG¡C §A¥i¥H¬Ý¨ì,oXMLHTTP ¹ê¨Òª«¥ó¬O³Q³]­p¦nªºAccess¤èªk±±¨îªº¡A³o¼Ë³]­p¬O爲¤F¨¾¤î³sÄò¦a³Ð«Ø©M¯}Ãa COM ¦øªA¾¹¡C
µM«á¡A§A¥i¥H¬Ý¨ì§Ú­Ìªº¨å«¬ªºSELECT´y­z, °£¤FLIKE¤l¥y¦³ÂIµyµy¤£¦P¥H¥~¡C HTTP »Ý­n§Ú­Ì·í¤Q¤»¦ì¤¸¦Ê¤À¤ñ¦r¤¸Åã¥Ü¨ì¹F25¢Hªº®É­Ô°h¥XÅã¥Ü¡]«ü¶i«×Åã¥Ü¡^¡A ¦b SQL server±µ¦¬¬d¸ß¤§«e , ³o­Ó­È±N·|Åܦ¨³æ¤@ªº¦Ê¤À¤ñ²Å¸¹¡C

µM«á¡A¥N½X¥Î¨ãÅ骺¬d¸ß­n¨D¨Ó³]¸mURL¡A¨Ã¥B³q¹LHTTPµo°eURL¨ìSQL SERVER¦øªA¾¹¡CSQL SERVER±µ¦¬¨ì³o­Ó¬d¸ß¡A¨Ã¥B³B²z¥¦¡A¥HXML¤è¦¡ªð¦^­È¡C³o¬O¦]爲§Ú­Ì¤w¸g¦b¡§¬d¸ß¡¨¤¤¥]§t¤FFOR XML¤l¥y¡C¦b³o­Ó¨Ò¤l¤¤¡AXMLªº®Ú¤¸¯À¥s°µ "results" ¡C§A±q¬d¸ß¦r¦ê¤¤¥i¥H¬Ý¥X¡C³o¬O«ö·Ó§Aªº²ßºD°t¸mªº¡C

¦¹®É¡A lcRetXML ¥]§t¤@­Ó¨Ó¦Û SQL serverªºXML¸ê®Æ¬yµ{¡C ¬JµM GetXML ¤èªk³Q VFP §@爲 SelectCmd ½Õ¥Î¡A§A¥i¥H±q GetXML ¤èªk¤¤ªð¦^³o­ÓÅܼƪº¤º®e¡A¦Ó¥B VFP ±N·|§â¸ê®Æ¬yµ{Âà´«¦¨¤@­Ó VFP ´å¼Ð¡C §A¥i¥H³q¹L°õ¦æ caXML µ{¦¡´ú¸Õ¡C ·|¥X²{¤@­Ó¥]§tªð¦^ªºXML¤å¥»¤º®eªºÂsÄýµ¡¤á¡C ¨Ï¥Î½Õ¸Õ¤u¨ã¤@¨B¤@¨B¬d¬Ý GetXML ¤èªk¡A¥i¥H¬Ý¨ì¦b³QÂà´«¨ì¤@­Ó VFP ´å¼Ð¨ÃÄÀ©ñ¤§«e , lcRetXML Åܼƪº­È¬OXML¤å¥»¡C

§ó·sXML¸ê®Æ
¤U¤@­Ó¨BÆJ¬O¨M©w¸Ó¦p¦ó¨Ï³o­Ó´å¼Ð¥i§ó·s¡A¥H«K©Ò§@ªº§ó§ï¯à³Qµo°e¦^ SQLXML ¦øªA¾¹¡C SQLXML ¯à¨Ï¥Î¤@­Ó¯S§OªºXML¤å¥»,§Y UpdateGram, §Q¥Î¥¦ª½±µ§â§ó·sµo°e¨ì¸ê®Æ®w¡C ¦b VFP7 ¤¤¡A¥i¥H¥Î XMLUpdateGram ¨ç¼Æ«Ø¥ß³o­Ó¤å¥»¡C ¥ÎVFP 8 ªº CursorAdapter ¡A UpdateGram Äݩʷ|¦Û°Ê«Ø¥ß¡C

²Ä¤@­Ó¨BÆJ¬O³]¸m updatable ÄݩʨåB«Ø¥ß¤@­Ó§ó·s«ü¥O¡C ¦bÃþ©w¸qªº¶}©l³]¸m³o¨ÇÄݩʡA¨Ã¦bCursorAdapterªºinit¨Æ¥ó¤¤¼W¥[¤@¦æ¥N½X¡A´£¨Ñ½Õ¥Î§ó·s©R¥Oªº¤èªk¡C
KeyFieldList = 'customerid'
Tables = 'customers'
UpdatableFieldList =
"companyname, contactname, contacttitle, "+;
"address, city, country "
UpdateNameList=
"customerid customers.customerid, " +
"companyname customers.companyname, " +
"contactname customers.contactname, " +
"contacttitle customers.contacttitle, " +
"address customers.address, " +
"city customers.city, country customers.country"
FUNCTION INIT() as Boolean
LOCAL llRetVal, lcMsg, laErr[1]
this.UpdateCmd = "this.UpdateXML()"
this.SelectCmd = "this.GetXML()"
** balance of code skipped...
ª`·N¡A§Ú­Ì¤w¸g¦binit¤èªk¤¤´À´«¤FÄÝ©Êªí¤¤ªº UpdateCmd ©M SelectCmd ³]¸m¡A¹ê»Ú¤W³Ì²×µ²ªG¬O¤@¼Ëªº¡C ¤£ºÞ«ç¼Ë, ³o¤@¬q¥N½Xªº²Ä¤@³¡¥÷²{¦b¬Ý°_¨Ó«Ü¼ô±x¡A¦b³oùاڭ̳]¸m¤F KeyFieldList ¡Atable¡A UpdatableFieldList ©M UpdateNameList ÄݩʡC ¨S¦³³o¨ÇÄݩʳ]¸m¡A´N¤£¥i¯à³Ð«Ø UpdateGram ¡C

µM«á¡A§Ú­Ì«Ø¥ß UpdateXML ¤èªk§@爲 CursorAdapter ªº UpdateCmd ¡C ¨S¦³°Ñ¼Æ¶Ç»¼µ¹ UpdateXML ¤èªk,©Ò¥H¡A©Ò¦³¨M©w§ó·sªº¤u§@¥²¶·³o­Ó¤èªkùسB²z¡CÁÙ¦³¡A¦]爲XML Ãþ«¬ªº CursorAdapter ¨S¦³Àq»{ªº§ó·s¾÷¨î, §A¥²¶·¼g¥N½X§â§ó·s¶Ç»¼µ¹XML¸ê®Æ·½¡C

¦b³o¤@¬q¥N½X¤¤¡A¨Ï¥Î XMLHTTP ª«¥ó¶Ç»¼§ó·s¨ì¦øªA¾¹¡C ³q¹LLoadXML¤èªk¸ü¤J UpdateGram Äݩʪº¤º®e¨ì XMLDOM( ¦bACCESS¤èªk¤¤) ¤§¤º,¥´¶}¨ì¦øªA¾¹ªº³s±µ,³]©w½Ð¨Dªº¤º®e爲XML, µM«áµo°e XMLDOM¡C©Ò¦³ªºµ²ªG³q¹L XMLHTTP ª«¥óªº ResponseText Äݩʪð¦^,±µµÛ¸Ë¸ü¨ì XMLDOM ¤¤¡A¨Ã¥B¤ÀªR¿ù»~¸ê°T¡C

¦pªG¨S¦³´£¥Ü¿ù»~,§ó·s¤w¸g¦¨¥\¡A¦Ó¥B¹Lµ{µ²§ô¡CµM¦Ó¡A¦pªG¦³¿ù»~, ´N·|産¥Í²Å¦X»yªkªº¿ù»~¸ê°T¤å¥»¡A¨Ã¥B¥]§t¦b¤@­Ó¦Û©w¸qªºERROR¨ç¼Æ¤¤¡A³o¼Ë TableUpdate ¨ç¼Æ´N¯à§ä¨ì§ó·s¥¢±Ñªº­ì¦]¡C ¦pªG¨S¦³³o¨Ç¥N½X¡A §Y¨Ï¦³°ÝÃDªº®É­Ô¡ATableUpdate Á`¬Oªð¦^¦¨¥\¸ê°T¡C

´ú¸Õ¤@¤U³o¬q¥N½X,¹B¦æ caXML µ{¦¡,¦b´å¼Ð¤¤§ó§ï¤@­ÓÄæ¦ì, µM«á¦b©R¥Oµøµ¡¤¤µo¥X TableUpdate¡C ¦pªG TableUpdate ¦¨¥\, §AÀ³¸Ó¯à¦b¦øªA¾¹¤W¬Ý¨ì§ó·sµ²ªG¡C¦pªG TableUpdate ¥¢±Ñ,§A»Ý­n¥Î AError ¨ç¼Æ±µ¦¬ SQL server産¥Íªº¿ù»~¸ê°T¡C
¦pªG§A¹ï UpdateGram ªº¤º®e·P¨ì¦n©_, §A¥i¥H¤@¨B¨B¬d¬ÝÃþªº UpdateXML ¤èªk¡A¨Ã¥B¬d¬Ý UpdateGram Äݩʪº¤º®e¡C µM¦Ó¡A¦pªG§A¤£¨ì¦³Ãö¸ê®ÆÅܤƪº¤èªk¤¤ (¦p UpdateCmd ¡A InsertCmd ©Î DeleteCmd Äݩʤº®e) ,§A¤]¤£¯à§¹¥þ§Ë©ú¥Õ UpdateGram Äݩʪº¤º®e¡C

list6Åã¥Ü·íContactNameÄæ¦ìªº«È¤áID³Q§ó§ï爲¡¥CACTU' «áUpdateGramªº¤º®e¡C

¥¿¦p§A¬Ý¨ìªº¡ASQLXML ¯à°÷Ū¨ú³o­Ó¤å¥»¨Ã¥B¯à°÷«Ü®e©ö¦a«Ø¥ß¤@­ÓUpdate-SQL »y¥y, µM«áµo°e¨ì SQL server¡C updg:sync¡]¦P¨B§ó·s¡^¤¸¯À¨Ï§ó·s¥ß§Yµo¥Í¡F¦]¦¹¡A¦pªG§A¦³¦h­Óªí»Ý­n§ó·s,§A¥i¥H§â¥¦­ÌÃöÁp°_¨Ó©ñ¨ì¤@­Ó UpdateGram¤¤, ½T©w§â¥L­Ì«Ê¸Ë¶i³o­Ó¤¸¯À¡A°õ¦æ¤@¦¸´N¥i¥H¥þ³¡§ó·s¡C
µ²§ô»y
¦b³o¤@½g¤å³¹¤¤¡A§Ú­Ì¯A¤Î¤F³\¦h¤è­±¡AÁ¿¤F·sªº CursorAdapter Ãþªº¥|ºØªí²{§Î¦¡¡C §A¤w¸g¾Ç¨ì¤F¦p¦ó³q¹L DataEnvironment ¡B CursorAdapter buileder¡BÃþ³]­p¾¹¡B©MPRG«Ø¥ß CursorAdapter ¡C §A¤]¤w¸gÁA¸Ñ¤F«Ø¥ß¥»¦a¡BODBC¡BOLE DB©ÎXML«¬ CursorAdapter Ãþªº°ò¥»¤èªk, ¨Ã¥B«ç¼Ë¨Ï³o¨ÇÃþ¥i§ó·s¡C

¤U¤@­Ó¨BÆJ¬O¦Ò¼{¦p¦ó§â³o¨ÇÃþÀ³¥Î¨ì§Aªºµ{¦¡¤¤¡C ¹ï§Ú¨Ó»¡¡Aı±o CursorAdapter À³¥Î¨ì¥ô¦óµ{¦¡ªº UI ¼h¤¤®ÄªG«Ü¦n,¦P®ÉÀ³¥Î©ó»Ý­n¤j¶q¹Lµ{¥N½Xªº³\¦h°Ó·~¶}µo¡CCursorAdapter¨Ã¤£¬O¤@­Ó³Ì¦nªº¿ï¾Üª«¥ó¥Î©ó¼h¨Ó¶Ç»¼¸ê®Æ¡C¦]爲¥¦§â©Ò¦³ªº¨Ó¦Û¸ê®Æ·½ªº¸ê®ÆÂà¤Æ¦¨¤@­Ó¤£«K©óÄâ±aªº´å¼Ð¡C

µM¦Ó¡A¦b¤@­Ó¨Ï¥Î CursorAdapter Ãþ¶i¦æ°Ó·~¶}µoªº¤è®×¤¤¡A¥¦¯à±µ¦¬¨Ó¦Û¸ê®Æ·½ªº¸ê®Æ, µM«á¥Î¼Ð·Çªº VFP ©R¥O©M¨ç¼Æ³B²z¸ê®Æ,³o¬O¦]爲¥¦産¥Íªº¬O¤@­Ó VFP ´å¼Ð¡C ¸ê®Æ¥i¥H³QÂà´«爲§ó¤@­Ó¸û¾A·íªºÃþ«¬,¨Ò¦pXML¡C

CursorAdapter ªº¥t¤@­Ó¦³§Q±ø¥ó¬O³q¥Îªº OOP ¤¶­±,¤£ºÞ»Ý­n¦s¨úªº¸ê®Æ¬O¤°麽Ãþ«¬¡C ¬Æ¦Ü¥ÎXML,»Ý­n¤j¶q¥N½X¨Ó¨ÏÃþ¥i§ó·s,§Ú­Ì¤´µM¥i¥H¥Î¨Ï¥Î CursorFill¨ú¦^¸ê®Æ¡A¥Î TableUpdate §ó·s¸ê®Æ, ¦Ó¥B¥Î AError ªð¦^¿ù»~, ¹³¨Ï¥Î¨ä¥LÃþ«¬ªº CursorAdapter¤@¼Ë¡C

°ò©ó¤@­Ó¨Æ¥ýªº¦Ò¼{©ÎªÌ­p¹º¡A§A·Q«Ø¥ß¤@­Ó¥i¥H­«´_¨Ï¥ÎªºCursorAdapterÃþ¡C ³o¨ÇÃþ¥i¥H¦bµ{¦¡¤§¶¡­«´_¨Ï¥Î©ÎªÌ¦b¦P¤@µ{¦¡¤º³¡²V¦X¨Ï¥Î¡A¨Ó§Î¦¨¤@ºØ§Aªºµ{¦¡³B²z¸ê®Æªº¼Ð·Ç¤èªk¡C

==========================================

¦³ºô¤Í°Ý¨Ï¥Îcursoradapter¬O§_Áٻݭntableupdate(),¤U­±¯Á©Ê¦Aµo¤@½g¤å³¹¡G
¦p¦ó³q¹L CursorAdapter ª«¥ó¨Ï¥Î TableUpdate ¨ç¼Æ§ó·s¸ê®Æ
³o¤@½g¤å³¹¾A¥Î©ó:vfp 8.0
ºK­n:
³o¤@½g¤å³¹°Q½×¤U¦C¦U¶µ¥DÃD:
1¡BTableUpdate ¥æ¤¬¦a¨Ï¥Î CursorAdapter Ãþ§ó·s«áºÝ¸ê®Æ¡C
2¡B¨Ï¥Îvfp 8.0 ªº·s CursorAdapter Ãþ³q¹LTableUpdate ¨ç¼Æ§ó·s¸ê®Æªº®É­Ô¦p¦ó³B²z§ó·s½Ä¬ð¡C
¸û¦hªº¸ê°T¡G
¥i¥H³q¹Lvfp 8.0 ªº CursorAdapter Ãþ¨ú¦^¨Ó¦Û¥»¦aªº©Î»·ºÝªº¸ê®Æ·½ªº¸ê®Æ¡C Àq»{±¡ªp¤U¡ACursorAdapter 産¥Íªº´å¼Ð¤£§ó·s«áºÝ¸ê®Æ¡C 爲¤F­n§ó·s«áºÝ¸ê®Æ,¥²¶·³]©w CursorAdapter ªº¤U¦C¦U¶µÄݩʭÈ:
InsertCmd
UpdateCmd
DeleteCmd
¦pªG§A¤£³]©w³o¨ÇÄݩʭÈ,§A¯à³q¹L³]©w¤U¦C¦U¶µ CursorAdapter ÄݩʭȦ۰ʦa産¥Í«áºÝ SQL §ó·s«ü¥O:
tables
KeyFieldList
UpdatableFieldList
UpdateNameList
SendUpdates
³B²z§ó·s½Ä¬ð
·í§A¨Ï¥Î CursorAdapter§ó·s«áºÝ¸ê®Æªº®É­Ô, TableUpdate ¨ç¼Æªð¦^ CursorAdapter ´å¼Ðªº§ó·sµ²ªG¡C ¦pªG¤@­Ó§ó·s½Ä¬ðµo¥Í,«áºÝ¸ê®Æªº§ó·s¤£¥i¯à¦¨¥\¡C µM¦Ó, TableUpdate ¥i¯à¤´µMªð¦^§ó·s¦¨¥\,¦]爲¦b CursorAdapter ´å¼Ð¤¤ªº¸ê®Æ³Q§ó·s¡C

§ó·s½Ä¬ð¬O«ü¡A¨Ï¥ÎªÌ¸Õ¹Ï½s¿è¤@±ø¨ú¦^«á¤w¸gµo¥Í§ïÅܪº°O¿ý¡C ¤U¦C¦U¶µ¬O§ó·s½Ä¬ð¯àµo¥Íªº±¡ªp:
1. User1 ¥´¶}¥Ñ«È¤áªí«Ø¥ßªº¤@­Ó´å¼Ð¡]cursor)¡C
2. User2 §ó·s²Ä¤@±ø°O¿ý¦Ó¥B´£¥æ§ó·s¡C
3. User1 §ó·s²Ä¤@±ø°O¿ý(¨Ï¥Î TableUpdate() ¨ç¼Æ).

¦¹®É¡A User1 ¦³¤@­Ó§ó·s½Ä¬ð: User1 ¥¿¦b¹Á¸Õ§ó·sªº«áºÝ°O¿ý¦b³Q¨ú¦^¤§«á¤w¸gµo¥Í§ïÅÜ¡C
DataSourceType ¥N½X¥Ü¨Ò¡G
¤U¦C¥Ü¨Ò¥N½X¨Ï¥Îvfp 8.0 ªºnative DataSourceType §ó·s SQL server Northwind ¸ê®Æ®wªº¤@µ§°O¿ý¡C ¬dÃÒ¬O§_°O¿ý³Q§ó·s,¦b§ó·s©R¥O¤¤ªþ¥[¤U¦C¥N½X:
CRLF+[EXECSCRIPT+(" if _tally=0"+CHR(10)"+error ('update conflit')"+CHR(10)+"ENDIF")]
¦b³oºØ±¡ªp¤U,Tableupdate() ªð¦^ (.F¡C ) ¦Ó¥B¤¹³\§A³B²z§ó·s¥¢±Ñ¡C
#DEFINE CRLF CHR(13)+CHR(10)
Local loCursor,ovfp
CLEAR

ON ERROR

Set Exclusive Off
Close Databases All
Set Multilocks On
loCursor = Createobject('CA')
* Load loCursor with the data specified in SelectCmd and display error message if error occurs.
loCursor.CursorFill()
GO top
* Display the value of the company name before update.
? "Before:",companyname
?
ovfp=Createobject("visualfoxpro.application.8")
ovfp.DoCmd("set exclusive off")
ovfp.DoCmd("update (_samples+'\northwind\customers') set companyname='Alfreds Futterkisted' where customerid='ALFKI'")
GO top
* Update the data in the cursor.
replace companyname WITH 'Alfreds Futterkiste'
* Update the back end.
retval=TABLEUPDATE(0,.F.,locursor.alias)
Messagebox("Tableupdate="+Transform(retval))

* If update conflict occurs, display the error.
if(retval=.F.)
LOCAL ARRAY errors(1)
AERROR(errors)
* Displays the errors.

IF "Update conflict"$errors[2]
MESSAGEBOX("Update Conflict-reverting changes")
=TABLEREVERT(.T.,locursor.alias)
ENDIF
endif
* Refresh the Cursor to get the updated data.
loCursor.CursorRefresh() && Get the data again to be sure
GO top
* Display the value of the company name after update.
?
? "After:",companyname

Define Class CA As CursorAdapter
Alias = 'test1'
DataSourceType = 'NATIVE'
SelectCmd = 'select * from (_samples+"\northwind\customers")'
Tables = 'Customers'
KeyFieldList = "customerid"
UpdatableFieldList = "companyname"
UpdateNameList = "customerid customers.customerid,companyname customers.companyname"
WhereType= 3
* This is a custom property, that is added to handle update conflicts. It does not do
* anything by itself. It is added below to the automatically-generated UpdateInsertCmd to
* test whether anything was actually updated.
ConflictCheckCmd =CRLF+[EXECSCRIPT("IF _tally=0" + CHR(10) + "ERROR('Update conflict')" + CHR(10) + "ENDIF")]

Procedure AfterUpdate
Lparameters cFldState, lForce, nUpdateType, UpdateInsertCmd, DeleteCmd, lResult
* To see why it will fail on the back end, look at the UpdateInsertCmd that is used
? "Update Command sent="+UpdateInsertCmd
* Swap the actual values in the command to see what occurred.
UpdateInsertCmd=Strtran(UpdateInsertCmd,[OLDVAL('customerid','test1')],Oldval('customerid','test1'))
UpdateInsertCmd=Strtran(UpdateInsertCmd,[OLDVAL('companyname','test1')],Oldval('companyname','test1'))
UpdateInsertCmd=Strtran(UpdateInsertCmd,[test1.companyname],test1.companyname)
? "With the OLDVAL() and test1.companyname evaluated the update statement is :"+UpdateInsertCmd
* Check tally.
? "Tally="+Transform(_Tally)

Procedure BeforeUpdate
Lparameters cFldState, lForce, nUpdateType, cUpdateInsertCmd, cDeleteCmd
cUpdateInsertCmd=cUpdateInsertCmd+this.ConflictCheckCmd

ENDDEFINE
¨Ï¥ÎSQL server DataSourceTypeªº¥Ü¨Ò¥N½X¡G
¤U¦C¥N½X¨Ï¥Î SQL server DataSourceType §ó·s SQL server Northwind ¥Ü¨Ò¸ê®Æ®wªº¤@µ§°O¿ý¡C ¬dÃÒ°O¿ý¬O§_³Q§ó·s,§â¤U¦C¥N½X¥[¤J§ó·s«ü¥O:
IF @@ROWCOUNT=0 RAISERROR (' Update
conflict.', 16, 1)
¦b³oºØ±¡ªp¤U¡ATableupdate() ªð¦^ (.F¡C ) ¦Ó¥B¤¹³\§A³B²z§ó·s¥¢±Ñ¡C
LOCAL loCursor,ovfp,nhnd,lsuccess

CLEAR
SET EXCLUSIVE OFF
CLOSE DATABASES ALL
SET MULTILOCKS ON

loCursor = CREATEOBJECT('CA')

* Load loCursor with the data specified in SelectCmd and display error message if error occurs.
IF !loCursor.CursorFill()
=AERROR(lar)
MESSAGEBOX(lar[2])
ENDIF


* Display the value of the company name before update.
? "Company Name Before Update:",companyname
?
* Create a connection handle for SQL Server so you can set up the update conflict.
nhnd=SQLSTRINGCONNECT([Driver=SQL Server; SERVER=<SQL SERVER NAME>; DATABASE=NORTHWIND])
=SQLEXEC(nhnd,[update customers set companyname='Alfreds Futterkiste' where customerid='ALFKI'])
=SQLDISCONNECT(nhnd)

* Now make a change to the local data, and then try to update it.
GO TOP
REPLACE companyname WITH 'Alfreds Futterkisted'

lsuccess=TABLEUPDATE(0,.F.,locursor.alias)
Messagebox("Tableupdate="+Transform(lsuccess))
* Error handling function. Displaying the error message if update conflict occurs.
IF !lsuccess
=AERROR(lar)
IF "Update conflict"$lar[2]
MESSAGEBOX("Update conflict!-Reverting changes")
=TABLEREVERT(.f.,locursor.alias)
ENDIF
ENDIF

* Get the current data from the CursorAdapter.
loCursor.CursorRefresh()
GO TOP

* Displaying the value of the company name after update.
?
?"Company Name After Update:", companyname

DEFINE CLASS CA AS CursorAdapter
Alias = 'test1'
SelectCmd = 'select * from customers'
Tables = 'Customers'
KeyFieldList = "Customerid"
UpdatableFieldList = "companyname"
UpdateNameList = "customerid customers.customerid,companyname customers.companyname"
WhereType= 3 && Key and modified

* This is a custom property that is added to handle update conflicts. It does not do
* anything by itself. It is added below to the automatically-generated UpdateInsertCmd to
* test whether anything was actually updated.
ConflictCheckCmd =";IF @@ROWCOUNT=0 RAISERROR (' Update conflict.', 16, 1)"


* Initializing the connectivity to Data source (SQL Server) by using ODBC driver.
PROCEDURE init
WITH THIS
.DataSourceType = 'ODBC'
.DataSource=SQLSTRINGCONNECT([Driver=SQL Server; SERVER=<SQL SERVER NAME>; DATABASE=NORTHWIND])
ENDWITH
ENDPROC

PROCEDURE BeforeUpdate
LPARAMETERS cFldState, lForce, nUpdateType, cUpdateInsertCmd, cDeleteCmd

? "Entering BeforeUpdate()"

cUpdateInsertCmd=cUpdateInsertCmd + THIS.ConflictCheckCmd
ENDPROC


PROCEDURE AfterUpdate

LPARAMETERS cFldState, lForce, nUpdateType, UpdateInsertCmd, DeleteCmd, lResult

* To see why it will fail on the back-end, look at the UpdateInsertCmd that is used.
? "Update Command sent="+UpdateInsertCmd

* Swap the actual values in the command to see what occurred.
lcActualCmd =Strtran(UpdateInsertCmd,[OLDVAL('customerid','test1')],Oldval('customerid','test1'))
lcActualCmd =Strtran(UpdateInsertCmd,[OLDVAL('companyname','test1')],Oldval('companyname','test1'))
lcActualCmd =Strtran(UpdateInsertCmd,[test1.companyname],test1.companyname)

? "With the OLDVAL() and test1.companyname evaluated the update statement is :"+UpdateInsertCmd
?
? "Leaving AfterUpdate()"
ENDPROC

* Destroying the connection.
PROCEDURE destroy
=SQLDISCONNECT(THIS.DataSource)
ENDDEFINE

ª`·N¡G³oºØ§ó·s¤è¦¡(¦p³o¤@¬q¥N½X©Ò¥Üªº)¤£¤ä´©§å¶q§ó·s¡C (¨Ò¦p,cursoradapter.batchupdatcount>1) ¡C¨Ï¥Î§å¶q§ó·sªº®É­Ô,¤U¦C¦U¶µ¨Æ¥ó¤£°Ê§@:
BeforeInsert
AfterInsert
BeforeUpdate
AfterUpdate
BeforeDelete
AfterDelete
¤T¦Ò
§ó¦hªº¸ê°T,vfp8À°§U¤¤ªº¤U¦C¦U¶µ¥DÃD¡C
¡§CursorAdapter Object Properties, Methods, and Events"
"Data Access Management Using CursorAdapters"
"Detecting and Resolving Conflicts"
"Locking Data"
"Management of Updates with Views"
"Programming for Shared Access"

=============================
vfp8¦Û±aªºcursoradapterÀ°§U¡G
¥Î Visual FoxPro,¥i¥H¥Îcursor adapters±µ¦¬¤ä´©¥H¤U¸ê®Æ·½Ãþ«¬ªº¥»¦a©Î»·ºÝ¸ê®Æ:
• ¥»¦aªº
• ¶}©ñ¦¡¸ê®Æ·½³s±µ(ODBC)
• ActiveX ¸ê®Æª«¥ó (ADO)
• ÂX®i¼Ð°O»y¨¥ (XML)
Cursoradapter Ãþ爲¤£¦Pªº¸ê®Æ·½Ãþ«¬§@爲¥»¦aÁ{®Éªí¨Ï¥Î´£¨Ñ¤ä´©. Cursoradapter ª«¥ó¨ã¦³¥H¤U¥\¯à:
• ÆF¬¡¦a¨Ï¥Î¤£¦Pªº¸ê®Æ·½.
• ¨Ï¥Î Cursoradapterª«¥ó¸ê®Æ·½©ÎªÌ¸ê®ÆÀô¹Ò .
• ¦b¸ê®Æ·½­­¨î½d³ò¤º¤À¨É¸ê®Æ.
• ÀH·N©w¸qCursoradapter ª«¥ó¥Í¦¨ªºÁ{®Éªíªºªíµ²ºc.
• ±±¨î Cursoradapter ª«¥ó¥Í¦¨ªºÁ{®Éªíªº¸ê®Æ¸Ë¸ü.
• ±q¤£¦P¸ê®Æ·½¥Í¦¨°ò©ó¸ê®Æ·½Ãþ«¬ªºVisual FoxPro Á{®Éªí.
• ¥Î Cursoradapter ÄݩʩM¤èªk±±¨î«ç¼Ë²K¥[¡B§ó·s¡B§R°£¸ê®Æ.
• °£¼Æ¾ÚÀô¹Ò¥H¥~¡A²K¥[ Cursoradapter ª«¥ó¨ìªí³æ¡Bªí³æ¶°©M¨ä¥L®e¾¹.
• ¥Î Cursoradapter Ãþ§@爲³æ¿Wªº¡BµL¼Æ¾ÚÀô¹ÒªºÃþ.
¹ï Cursoradapter ª«¥ó¨Ó»¡,¸ê®Æ·½¥u¬O¤@­Ó½Ķ¼h¡A¥¦±q¸ê®Æ·½Àò¨ú¸ê®Æ¥Í¦¨ Visual FoxPro Á{®Éªí.
ª`·N¡G Visual FoxPro ¤£¤ä´©Cursoradapter ª«¥ó«Ø¥ß³s±µÃö«Y. ¦ý¬O, ¥i¥H¦b¥Í¦¨ªºÁ{®Éªí¤§¶¡«Ø¥ß³s±µÃö«Y.
·QÁA¸Ñ§ó¦h Cursoradapter, ¸ê®ÆÀô¹Ò, ©M´å¼ÐÃþªº¸ê°T,½Ð¬Ý¡G Cursoradapter Class, DataEnvironment Object, ©M Cursor Object.
¥ÎTABLEUPDATE()©MTABLEREVERT()¨ç¼Æ¹ê²{¸ê®Æ¤¬°Ê
TABLEUPDATE( ) ¨ç¼Æ¯à°÷ÃѧO¨Ã¥B¥Î Cursoradapter ª«¥ó¤u§@. TABLEUPDATE( ) delegates its operations to the cursor adapter associated with the cursor. TABLEREVERT( ) operates on Cursoradapter objects in the same way as other buffered cursors.
·QÁA¸Ñ§ó¦hªº Cursoradapter ª«¥ó«ç¼Ë¼vÅTTABLEUPDATE( ) ©M TABLEREVERT( ) ¨ç¼Æªº¦æ爲, ½Ð¬d¬Ý TABLEUPDATE( ) Function ©M
TABLEREVERT( ) Function.
Automatic Updating and Cursoradapters
Visual FoxPro¦b¥»¦a©M»·ºÝµø¹Ï¤¤¦Û°Ê産¥Í SQL INSERT, UPDATE, ©M DELETE ©R¥O. ¥Î Cursoradapter ª«¥ó,¥i¥H«ü©w¡B±±¨îVisual FoxPro «ç¼Ë¾Þ§@SQL INSERT, UPDATE, ©M DELETE ©R¥O.
·í Cursoradapter InsertCmd, UpdateCmd, ©M DeleteCmd ÄÝ©Ê爲ªÅªº®É­Ô¡A Visual FoxPro ¦Û°Ê産¥Í¼Ð·ÇªºSQL©R¥O. §A¥²¶·½T©w¨º¨Ç¦Û°Ê産¥Íªº©R¥O¬O§_¾A¦X¨Ï¥Îªº¸ê®Æ·½.­n¦Û°Ê産¥ÍSQL INSERT, UPDATE, ©M DELETE ©R¥O,§A¥²¶·³]©w¤U­±ªº Cursoradapter¯S©wÄÝ©Ê:
• Tables
• KeyFieldList
• UpdatableFieldList
• UpdateNameList
Tables ©M UpdateNameList Äݩʭn²Å¦X¥H¤U³W«h:
• Tables
¦pªG¤¹³\¦Û°Ê§ó·s,¥²¶·«ö¶¶§Ç¦C¥X§Æ±æ¦b SQL INSERT, UPDATE, ©M DELETE ©R¥O¤¤Åã¥Üªºªíªº¦WºÙ.
• UpdateNameList
• ¥²¶·«ü©w¤@­Ó¥]§t¦¨¹ï¥X²{ªº¡B¥»¦a©M§¹¾ãªº»·ºÝ¸ê®ÆÄæ¦ìªº¦Cªí¡A¥Î¤À¸¹¤À¹j¡C ¨S¤@¹ïÄæ¦ì¦W¤¤¡A¥»¦aªº¦b«e¡A»·ºÝªº¦b«á¡C§¹¾ãªº»·ºÝÄæ¦ì¦WÀ³¸Ó³o¼Ë¼g¡G<»·ºÝªí¦W>, <»·ºÝÄæ¦ì¦W>, <»·ºÝªí¦W> ¥²¶·©MTables Äݩʤ¤ªº¦W¦r¤@­P.
¦pªG§A³]¸m¥H¤UCursoradapter ªºÄÝ©Ê爲 True (.T.)¡A¥²¶·«ü©wÃöÁäÄæ¦ì:
• AllowInsert
• AllowUpdate
• AllowDelete
§A·QÁA¸Ñ§ó¦hÃö©óSQL ªº¦Û°Ê§ó·s©R¥O,½Ð¬Ý INSERT - SQL Command, UPDATE - SQL Command, ©M DELETE - SQL Command.
§å¶q§ó·s¡]Batch Updates¡^
¦pªG Cursoradapter BatchUpdateCount Äݩʪº­È¤j©ó1, Cursoradapter ª«¥ó¨Ï¥Î§å¶q§ó·s ¡C ¦P®É¥²¶·¨ã³Æ¥H¤U±ø¥ó:
• Cursoradapter ª«¥ó³]¸m爲©Ò¦³¤¹³\ªº¾Þ§@¨Ï¥Î¬Û¦PªºODBC³s±µ¡A¥]¬AAllowInsert, AllowUpdate, ©M AllowDeleteÄݩʤ¤³]¸mªºINSERT¡AUPDATE,©MDELETE¾Þ§@¡C.
• Cursoradapter ª«¥ó³]¸m爲©Ò¦³¤¹³\ªº¾Þ§@¨Ï¥Î¬Û¦PªºADODB ©R¥Oª«¥ó¡C
• Cursoradapter ª«¥ó©Ò¦³³Q¤¹³\ªº¾Þ§@¨Ï¥Î "XML" §@爲¸ê®Æ·½¡C
¦pªG¨Ï¥Î§å¶q§ó·s, ¤U¦C Cursoradapter ¨Æ¥ó¤£µo¥Í¡G
• BeforeInsert
• AfterInsert
• BeforeUpdate
• AfterUpdate
• BeforeDelete
• AfterDelete
¦pªG§å¶q§ó·s¥¢±Ñ, Visual FoxPro ¹Á¸Õ¦b¸Ó§å¸ê®Æ¤¤ªº¨C¤@¦æµo°e¤@­Ó¤À´²ªº§ó·s¡AµM¦Ó¡A¦CÁ|ªº¨Æ¥ó¤£·|µo¥Í¡C
§ó¦hªº¬ÛÃö¸ê°T, °Ñ¨£ BatchUpdateCount Property.
¦Û°Ê§ó·s¡]Automatic Updating¡^©M ActiveX Data Objects (ADO)
¥Î ADO¤u§@ªº®É­Ô, ¥i¥H¥Î¨âºØ¿ìªkµo°e§ó·s:
• ¨Ï¥Î Cursoradapter ª«¥ó¡A³q¹L¦bCursoradapter CursorFill ¤èªk¤¤¨Ï¥Î ADO °O¿ý¶°ª«¥óµo°e§ó·s
• ·í¨Ï¥Î ADO°O¿ý¶°°õ¦æ¦Û°Ê§ó·sªº®É­Ô, ³]¸mursorAdapter InsertCmdDataSource, UpdateCmdDataSource, ©M DeleteCmdDataSource Äݩʪº®É­Ô¡A¥²¶·¿í´`¤U¦C³W«h:
• ADO°O¿ý¶°¥²¶·¬O¥iŪ¼gªº¨Ã¥B¼Ð°O爲¥i¥Î¡C
• ·í¨Ï¥Î¥Î¤áºÝ°O¿ý¶°ª«¥óªº®É­Ô¡A®Ññ¥²¶·Á`¬O¥i¥Î¡C
• Bookmarks might be available when using Keyset or Static server-side cursors when supported by the OLE DB Provider.
• «ö·Ó¤@­ÓÄæ¦ì¤@­ÓÄæ¦ìªº³W«h¶i¦æ§ó·s.§ó·s§¹¤@±ø°O¿ý¥H«á¡A Cursoradapter ª«¥ó¦bADO°O¿ý¶°¤¤´M§ä­ì©l°O¿ýt, ¥Î¨Ó§ïÅÜ¥i§ó·sÄæ¦ìªº­È, ¨Ã¥B½Õ¥ÎADO°O¿ý¶°ªºupdate¤èªk¡C Cursoradapter ª«¥ó¤£½Õ¥Îado°O¿ý¶°ªºupdatebatch¤èªk¡A ¦]¦¹, §Aªºµ{¦¡»Ý­n¦b«ê·íªº®É­Ô©ú½T¦a½Õ¥Î UpdateBatch¤èªk¡C
·í¨Ï¥Î³o­Ó¤èªkµ{¦¡ªº®É­Ô, »Ý­n«ö¥H¤U¤èªk³]¸m Cursoradapter ª«¥ó:
THIS.DataSourceType="ADO"
THIS.UpdateCmdDataSourceType=""
¥i¥H¥Î¸ê®ÆÀô¹Ò¡]DataEnvironment¡^©M Cursoradapter builders ¨Ó«Ø¥ß¤@­Ó¥i§ó·sªºªí³æ¡A©ÎªÌ¨Ï¥Î¸ê®ÆÀô¹Ò DataEnvironment ©M Cursoradapter Ãþ®w¡A©ÎªÌ¦bCursoradapter Builder¤¤¨Ï¥Î AutoUpdate tab ¨î©w¤@­Ó¥DÃöÁäÄæ¦ì,§ó·sÄæ¦ì,©ÎªÌ¨ä¥L­n¨Dªº¸ê°T¡C
• ³q¹L¤@­Ó¦Û©w¸qªº©ÎªÌ¦Û°Ê産¥Íªº©R¥O¡A³q¹L Cursoradapter ª«¥ó¦V¸ê®Æ®wª½±µµo°e¤@­Ó§ó·s¡C
• ·í°õ¦æ¦Û°Êª½±µ§ó·s, Cursoradapter ª«¥ó»Ý­n¤@­Ó ADOª«¥ó¡A¨ä ActiveConnection Äݩʳ]¸m¦¨¶}©ñªºADO³s±µ¼Ò«¬¡C
• ¥Î³oºØ¤èªkªº®É­Ô, »Ý­n¥Î¥H¤U¤èªk³]¸mCursoradapterª«¥ó :
THIS.UpdateCmdDataSourceType="ADO"
THIS.UpdateCmdDataSource=NewADODBCommandObject
¦b³o­Ó¤èªkùؤ£±ÀÂ˨ϥΠTHIS.DataSourceType="ADO" ¡C
¦Û°Ê§ó·s©M XML
Cursoradapter ª«¥ó¨Ï¥ÎXML¸ê®Æ·½®É¡A¤£¦Û°Ê産¥ÍSQL INSERT, UPDATE, ©M DELETE©R¥O¡A¦]爲¤w¸g¦s¦b¦n¦h産¥ÍXMLªº¤â¬q¡C µM¦Ó,¥i¥H¨Ï¥ÎCursoradapter ª«¥ó産¥Í¤@­Ó XML UpdateGram ¡A©ñ¦b Cursoradapter UpdateGram ÄÝ©Ê.
¾¨ºÞCursoradapter ª«¥ó¯à産¥ÍXML UpdateGram, §A¥²¶·¨Ï¥Î«ê·íªº¨ó©w¨Ó¹ê²{³Ì²×§ó·s¡C¨Ò¦p¡ASQL XML¡]HTTP¡^, SQL XML OLE DB, ©ÎªÌ XML Web service to .NET.
¨Ï¥Î XML ¸ê®Æ·½©M産¥Í XML UpdateGramsªº®É­Ô¥²¶·¿í´`¥H¤U³W«h:
• ¥²¶·¦b Cursoradapter InsertCmd, UpdateCmd, and DeleteCmd Äݩʤ¤«ü©w¨ãÅ骺©R¥O¡AVisual FoxPro¯à°÷¾Ú¥H¶i¦æ¥¿½Tªº´¡¤J¡B§ó·s¡B©M§R°£¾Þ§@¡C ¦pªG¨Ï¥Î§å¶q§ó·s, Cursoradapter BatchUpdateCount Äݩʭȥ²¶·¤j©ó1, UpdateCmd ¦b§å¶q¤¤¥u°õ¦æ¤@¦¸¡C
• ¤U¦C Cursoradapter Äݩʥ²¶·³]¸m爲 "XML":
• InsertCmdDataSourceType
• UpdateCmdDataSourceType
• DeleteCmdDataSourceType
¦pªG³o¨ÇÄݩʤ£³]¸m爲"XML", Visual FoxPro °õ¦æ UpdateCmd, InsertCmd, DeleteCmd Äݩʤ¤ªº©R¥O¦Ó¥B¤£産¥ÍXML UpdateGram.
• ­n·Q¥¿½Tªº«Ø¥ßXML §ó·s¡]UpdateGram¡^, Cursoradapter »Ý­n Tables, UpdatableFieldList, UpdateNameList Äݩʤ¤¥]§t½T©wªº­È¡C Cursoradapter ¥i¥H³q¹L¦bTables, UpdatableFieldList,©M UpdateNameList Äݩʤ¤«ü©w«ê·íªº¦WºÙ¨Ó産¥Í¤@­Ó¦hªí§ó·s¡C¦]¦¹, ¥i¥H§ó·s¥ÎXMLUPDATEGRAM( )¨ç¼Æ産¥Íªº³s±µ¦h­Óªíªº´å¼Ð¡C§ó¦hªº¸ê°T,½Ð¬Ý XMLUPDATEGRAM( ) Function.
• Cursoradapter ¨Ï¥Î WhereType ÄÝ©Ê産¥ÍXML UpdateGram ªº before ¨Æ¥ó¡C¦]¦¹, ·í§A°õ¦æ¤@­Ó§ó·s©Î§R°£ªº¾Þ§@®É¡A KeyFieldList ©M UpdatableFieldList Äݩʥ²¶·¥]§t¤@­Ó¥DÃöÁäÄæ¦ì.§ó¦hªº¸ê°T,°Ñ¨£ WhereType Property.
• ¦pªG³]¸m¤F¦æ½w½Ä, ©ÎªÌ BatchUpdateCount ªº­È¬O1, Visual FoxPro 爲¨C­Óupdate, insert, delete ¾Þ§@«Ø¥ß¤@­ÓXML UpdateGram §ó·s¡C
¦pªG³]¸m爲ªí½w½Ä, ¨Ã¥B¨Ï¥Î§å¶q§ó·s, §YatchUpdateCount ªº­È¤j©ó1, Visual FoxPro 爲¥þ³¡ªº§å¶q³Ð«Ø¤@­Ó XML§ó·s¡C ¦¹ºØ¤è¦¡¤U, ¥²¶·¨Ï¥ÎTABLEUPDATE( ) ¨ç¼Æ°õ¦æXML§ó·s¡C
¦^³»ºÝ
À˵ø·|­û­Ó¤H¸ê®Æ µo°e¨p¤H°T®§
akwang



µù¥U®É¶¡: 2004-11-06
¤å³¹: 24
¨Ó¦Û: ccf

²Ä 2 ¼Ó

µoªíµoªí©ó: ¬P´Á¤­ ¤@¤ë 27, 2006 11:13 pm    ¤å³¹¥DÃD: ¤Þ¨¥¦^ÂÐ

这½g¤å³¹写ªº¤Ó¦n¤F
¨þ¨þ¡A¤£ª¾¹D这Ïú¥Îªk过时¤F吗¡H
¦^³»ºÝ
À˵ø·|­û­Ó¤H¸ê®Æ µo°e¨p¤H°T®§
impotence



µù¥U®É¶¡: 2005-02-21
¤å³¹: 135
¨Ó¦Û: Hong Kong

²Ä 3 ¼Ó

µoªíµoªí©ó: ¬P´Á¤G ¤G¤ë 07, 2006 12:02 pm    ¤å³¹¥DÃD: ¤Þ¨¥¦^ÂÐ

ÁÂÁ¤À¨É ~~~
_________________
¤@­Ó±`±`§Ñ°O Command ªº¤H !
¦^³»ºÝ
À˵ø·|­û­Ó¤H¸ê®Æ µo°e¨p¤H°T®§
±q¤§«eªº¤å³¹¶}©lÅã¥Ü:   
µoªí·s¥DÃD   ¦^ÂÐ¥DÃD    VFP ·R¥ÎªÌªÀ°Ï ­º­¶ -> VFP °Q½×°Ï ©Ò¦³ªº®É¶¡§¡¬° ¥x¥_®É¶¡ (GMT + 8 ¤p®É)
²Ä1­¶(¦@1­¶)

 
«e©¹:  
±z µLªk ¦b³o­Óª©­±µoªí¤å³¹
±z µLªk ¦b³o­Óª©­±¦^ÂФ峹
±z µLªk ¦b³o­Óª©­±½s¿è¤å³¹
±z µLªk ¦b³o­Óª©­±§R°£¤å³¹
±z µLªk ¦b³o­Óª©­±¶i¦æ§ë²¼
±z µLªk ¦b³o­Óª©­±ªþ¥[ÀÉ®×
±z µLªk ¦b³o­Óª©­±¤U¸üÀÉ®×


Powered by phpBB © 2001, 2005 phpBB Group
¥¿Å餤¤å»y¨t¥Ñ phpbb-tw ºûÅ@»s§@