我經(jīng)常聽(tīng)一些人大談把兩層CS結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層CS結(jié)_第1頁(yè)
我經(jīng)常聽(tīng)一些人大談把兩層CS結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層CS結(jié)_第2頁(yè)
我經(jīng)常聽(tīng)一些人大談把兩層CS結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層CS結(jié)_第3頁(yè)
我經(jīng)常聽(tīng)一些人大談把兩層CS結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層CS結(jié)_第4頁(yè)
我經(jīng)常聽(tīng)一些人大談把兩層CS結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層CS結(jié)_第5頁(yè)
已閱讀5頁(yè),還剩96頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第二章 編程我經(jīng)常聽(tīng)一些人大談把兩層C/S結(jié)構(gòu)的應(yīng)用轉(zhuǎn)為三層C/S結(jié)構(gòu)的應(yīng)用,無(wú)論說(shuō)的,還是聽(tīng)的,都興高采烈,頻頻點(diǎn)頭:好,好!轉(zhuǎn)吧。不過(guò),具體怎么“轉(zhuǎn)”呢?是不是把兩層C/S結(jié)構(gòu)的程序放到什么容器里“煮”一下,再取出來(lái)就可以“吃”了?當(dāng)然不行,看來(lái)一個(gè)“轉(zhuǎn)”字還頗有點(diǎn)兒學(xué)問(wèn)。如果您原來(lái)靠游泳過(guò)河,那我教您一種劃船過(guò)河的方法,這條船就是中間件CICS當(dāng)然您不能靠劃船的經(jīng)驗(yàn)來(lái)驅(qū)動(dòng)它,CICS需要的是編程。學(xué)劃船很簡(jiǎn)單,學(xué)CICS編程也一樣簡(jiǎn)單,讀了本章的內(nèi)容就會(huì)知道。如果讀者想用COBOL或JAVA來(lái)開(kāi)發(fā)CICS的服務(wù)程序,請(qǐng)參閱CICS的其它技術(shù)資料,這里只提供了C語(yǔ)言的例子。不過(guò),這里提供了

2、幾乎所有常用的前端開(kāi)發(fā)工具作為CICS客戶的例子,也許這正是您所需要的,那么,請(qǐng)認(rèn)真閱讀后面的內(nèi)容。如果您已經(jīng)有足夠多的預(yù)備知識(shí),可以先閱讀下一章,在建好一個(gè)實(shí)驗(yàn)環(huán)境后,再回到本章。2.1 建立一個(gè)簡(jiǎn)單的CICS應(yīng)用CICS程序:GETTIME我們將要看到的這個(gè)CICS程序基本沒(méi)有用到CICS強(qiáng)大的事務(wù)處理監(jiān)控能力,所以更象是一個(gè)兩層C/S的應(yīng)用。但是因?yàn)樗绱撕?jiǎn)單,我還是把它做為您學(xué)習(xí)CICS的入門程序。做過(guò)UNIX或NT的服務(wù)程序(UNIX經(jīng)常叫DAEMON程序)朋友,會(huì)發(fā)現(xiàn)CICS服務(wù)程序非常容易實(shí)現(xiàn),因?yàn)槟槐厝ヌ幚鞸ocket、Named Pipe或FIFO之類的東西。是的,如果不考

3、慮價(jià)格因素,用CICS去實(shí)現(xiàn)許多一般的服務(wù)程序可是個(gè)省事的好辦法。設(shè)想某公司要投資開(kāi)發(fā)一個(gè)叫GETTIME的服務(wù)程序,其功能是公布服務(wù)器的時(shí)間,供他們的各種前端客戶程序使用。這些程序必須能運(yùn)行于各種常用的UNIX平臺(tái)和WINDOWS NT,甚至可以移植到AS400和IBM大型機(jī)上。正在公司的編程高手們紛紛摩拳擦掌,準(zhǔn)備大干一場(chǎng)時(shí),一個(gè)初級(jí)的CICS程序員突然宣布他已在5分鐘內(nèi)完成了任務(wù),并將得到一筆可觀的報(bào)酬有這種好事嗎?那我們不妨就來(lái)看看GETTIME的CICS解決方案。這是C語(yǔ)言作的CICS服務(wù)程序的清單(注意,這個(gè)源程序可以不加修改的運(yùn)行在支持CICS的各種操作系統(tǒng)平臺(tái)上):#inclu

4、de <time.h>#include "easycics.h"void main()struct tm *newtime;time_t aclock;if( InitEasyCics() ) ExitEasyCics();/* A */BeginWrite();/* B */time( &aclock );newtime= localtime( &aclock );SetValue( "TIME", asctime(newtime) ); /* C */ExitEasyCics();/* D */清單 2-1-1 (gett

5、ime.ccs)客戶程序更加簡(jiǎn)單,下面是一些例子:1、ANSI C的客戶程序見(jiàn)清單2-1-2:#include "ec.h"void main()char s200;ConnectServer( "CICSNT01", "TEST", "TEST" );/* A */CallProgramAndCommit("GETTIME");/* B */GetValue( "TIME", s );/* C */puts(s);清單 2-1-2以下是運(yùn)行結(jié)果:D:cics>gett

6、imeThu Jan 27 17:35:14 2000清單 2-1-32、使用OLE可以支持Windows上的各種開(kāi)發(fā)工具,例如:Visual C,Visual Basic,Power Builder,Delphi,C+Builder,Lotus Notes,Internet Explorer等。下面是Visual Basic的例子(PowerBuilder和Delphi的客戶程序幾乎可以照搬這段代碼):Sub main()Dim oEc As ObjectDim r% Set oEc = CreateObject("EasyCics.App")A r = oEc.Conn

7、ectServer("CICSNT01", "TEST", "TEST")B oEc.CallProgramAndCommit "GETTIME"C MsgBox oEc.GetValue("TIME")DEnd Sub清單 2-1-4以下是運(yùn)行結(jié)果:圖 2-1-13、如果使用JAVA,可以無(wú)須重新編譯地移植您的程序。下面是JAVA的例子:import easycics.*;public class GetTimestatic public void main( String astrArg )

8、tryApp oEc = new easycics.App();/AoEc.ConnectServer("CICSNT01", "TEST", "TEST");/BoEc.CallProgramAndCommit("GETTIME");/C/Dcatch(ServerErrorException se)/E清單 2-1-6以下是運(yùn)行結(jié)果:D:cics>java GetTimeSat Jan 29 21:22:16 2000清單 2-1-7我還能羅列出一大堆編程工具訪問(wèn)CICS的源碼,是的,它們非常類似。您可能

9、注意到了GetValue、SetValue、ConnectServer、CallProgramAndCommit,是的,記住這些就差不多了,常用的調(diào)用很少,使用CICS確實(shí)非常簡(jiǎn)單。我們先來(lái)分析一下服務(wù)程序,就是清單2-1-1展示的C程序。這個(gè)程序采用的接口方法叫做EasyCICS,所以我們引入了“easycics.h”頭文件,上面列舉的那些函數(shù)都是EasyCICS的函數(shù)。InitEasyCics函數(shù)的作用是初始化環(huán)境,如果返回值非零,表示初始化失敗。ExitEasyCics函數(shù)的作用是退出CICS服務(wù)程序,并把返回信息傳給客戶程序。注意,任何情況下退出CICS服務(wù)程序,必須調(diào)用ExitEas

10、yCics函數(shù),或與其相當(dāng)?shù)腃ICS API,不能使用操作系統(tǒng)調(diào)用exit或_exit等。程序在A處的意思是,如果初始化失敗,就退出CICS服務(wù)程序。程序在B處調(diào)用了BeginWrite函數(shù),表示開(kāi)始寫通信用的公共數(shù)據(jù)區(qū),它的真正作用是清除該公共數(shù)據(jù)區(qū)。程序在C處調(diào)用了SetValue函數(shù),其作用是把一個(gè)字符串作為值賦予一個(gè)關(guān)鍵字(也是一個(gè)字符串),并存儲(chǔ)在公共數(shù)據(jù)區(qū)。在這里,”TIME”是關(guān)鍵字,日期和時(shí)間字符串(由asctime函數(shù)獲得)是值。這樣做的意義何在?我們可以把很多值賦予不同的關(guān)鍵字,只要根據(jù)關(guān)鍵字就可以取出這些值。于是,客戶機(jī)和服務(wù)器就可以利用這種方法進(jìn)行通信。程序在D處調(diào)用了

11、ExitEasyCics函數(shù),任何情況下退出CICS服務(wù)程序,必須調(diào)用該函數(shù)。只有C源程序還不夠,我們還需要把它編譯成執(zhí)行文件或庫(kù)文件(在Windows NT系統(tǒng),CICS服務(wù)程序最終要被編譯成為.DLL文件,即動(dòng)態(tài)連接庫(kù))。一些程序員習(xí)慣于使用集成編譯工具,但無(wú)法使用在UNIX等操作系統(tǒng)。我們采用更加通用的makefile方式進(jìn)行編譯。以下是在NT系統(tǒng)中,編譯GETTIME服務(wù)程序的makefile(在各種UNIX系統(tǒng),要進(jìn)行必要的修改):gettime.dll: gettime.ccsset USERLIB=easycics.objcicstcl -e -d -lC gettime.ccs

12、清單 2-1-8如果您使用的是CICS for Windows NT,您可以使用圖形界面把編譯好的程序(gettime.dll)加入CICS域(region)。請(qǐng)參照如下插圖:圖 2-1-2 (選擇管理界面程序)圖 2-1-3 (在CICS域中選擇program資源設(shè)置)圖 2-1-4 (program資源設(shè)置)圖 2-1- 5(program資源設(shè)置)當(dāng)然,也可以使用如下指令(注意大小寫):cicsadd -c pd -r CICS域名 你的程序名(GETTIME) PathName=路徑 RSLKey=public再看看ANSI C的客戶程序,就是清單2-1-2展示的C程序。這個(gè)程序采用的

13、接口方法也是EasyCICS,所以我們引入了“ec.h”頭文件(注意服務(wù)程序使用的是叫做“easycics.h”的頭文件)。程序在A處執(zhí)行了ConnectServer函數(shù)。該函數(shù)的第一個(gè)參數(shù)是CICS的系統(tǒng)名稱,相當(dāng)于CICS域(Region)的連接字符串;函數(shù)的后兩個(gè)參數(shù)分別是CICS的用戶名稱和口令。程序在B處執(zhí)行了CallProgramAndCommit函數(shù),我們一般使用此函數(shù)來(lái)調(diào)用服務(wù)程序(Program)。該函數(shù)的唯一參數(shù)就是要調(diào)用的CICS的服務(wù)程序名稱,在此處,即GETTIME程序。程序在C處執(zhí)行了GetValue函數(shù),此函數(shù)通過(guò)其參數(shù)指定的關(guān)鍵字來(lái)獲取服務(wù)器方面通過(guò)SetVal

14、ue函數(shù)來(lái)設(shè)置的字符串值。注意,可以通過(guò)多個(gè)SetValue和GetValue函數(shù)來(lái)傳遞多個(gè)字符串值。另外,如果客戶機(jī)方面調(diào)用SetValue函數(shù),而服務(wù)器方面調(diào)用GetValue函數(shù)也完全可以。SetValue和GetValue函數(shù)對(duì)是EasyCICS傳遞值的標(biāo)準(zhǔn)方法之一。這個(gè)客戶程序的makefile如下:all: gettime.exegettime.exe: gettime.objlink gettime.obj ec.obj cclwin32.libgettime.obj: gettime.ccl -c gettime.c清單 2-1-9再看看使用Visual Basic的客戶程序,

15、就是清單2-1-4展示的程序。這個(gè)程序采用EasyCICS組件。使用面向?qū)ο蟮男g(shù)語(yǔ),我們將反復(fù)提到組件的“方法”,或接口的“方法”,而不能說(shuō)組件或接口的函數(shù)。程序在A處調(diào)用了VB的函數(shù)CreateObject創(chuàng)建了連接EasyCICS的對(duì)象。程序在B處執(zhí)行了組件的ConnectServer方法。該方法的第一個(gè)參數(shù)是CICS的系統(tǒng)名稱,相當(dāng)于CICS域(Region)的連接字符串;函數(shù)的后兩個(gè)參數(shù)分別是CICS的用戶名稱和口令。程序在C處執(zhí)行了組件的CallProgramAndCommit方法,我們一般使用此函數(shù)來(lái)調(diào)用服務(wù)程序(Program)。該函數(shù)的唯一參數(shù)就是要調(diào)用的CICS的服務(wù)程序名稱

16、,在此處,即GETTIME程序。程序在D處執(zhí)行了組件的GetValue方法,此函數(shù)通過(guò)其參數(shù)指定的關(guān)鍵字來(lái)獲取服務(wù)器方面通過(guò)SetValue函數(shù)來(lái)設(shè)置的字符串值。注意,可以通過(guò)多個(gè)SetValue和GetValue函數(shù)來(lái)傳遞多個(gè)字符串值。另外,如果客戶機(jī)方面調(diào)用SetValue函數(shù),而服務(wù)器方面調(diào)用GetValue函數(shù)也完全可以。SetValue和GetValue函數(shù)對(duì)是EasyCICS傳遞值的標(biāo)準(zhǔn)方法之一。Visual Basic不需要makefile之類的東西,可見(jiàn)使用組件是多么的簡(jiǎn)單。我們?cè)赑owerBuilder和Delphi中,都是通過(guò)組件訪問(wèn)CICS。最后,我們研究一下JAVA的例

17、子。JAVA通過(guò)GateWay來(lái)訪問(wèn)CICS Client,我們也可以采用EasyCICS,所以,我們首先引入了easycics.*,這為我們?cè)L問(wèn)CICS Client奠定了基礎(chǔ)。程序在A處創(chuàng)建了easycics.App的類實(shí)例對(duì)象。程序在B處執(zhí)行了類的ConnectServer方法。該方法的第一個(gè)參數(shù)是CICS的系統(tǒng)名稱,相當(dāng)于CICS域(Region)的連接字符串;函數(shù)的后兩個(gè)參數(shù)分別是CICS的用戶名稱和口令。程序在C處執(zhí)行了類的CallProgramAndCommit方法,我們一般使用此函數(shù)來(lái)調(diào)用服務(wù)程序(Program)。該函數(shù)的唯一參數(shù)就是要調(diào)用的CICS的服務(wù)程序名稱,在此處,即

18、GETTIME程序。程序在D處執(zhí)行了類的GetValue方法,此函數(shù)通過(guò)其參數(shù)指定的關(guān)鍵字來(lái)獲取服務(wù)器方面通過(guò)SetValue函數(shù)來(lái)設(shè)置的字符串值。注意,可以通過(guò)多個(gè)SetValue和GetValue函數(shù)來(lái)傳遞多個(gè)字符串值。另外,如果客戶機(jī)方面調(diào)用SetValue函數(shù),而服務(wù)器方面調(diào)用GetValue函數(shù)也完全可以。SetValue和GetValue函數(shù)對(duì)是EasyCICS傳遞值的標(biāo)準(zhǔn)方法之一。JAVA也不需要makefile之類的東西,而且可以不用重新編譯,就移植到各種操作系統(tǒng)平臺(tái)上。也許您對(duì)對(duì)上面介紹的示例程序GETTIME不以為然,因?yàn)樗?jiǎn)單了。那么,下面將介紹另一個(gè)示例程序TELEC

19、OM,一個(gè)同樣簡(jiǎn)單但功能健全的標(biāo)準(zhǔn)示例程序。您可以通過(guò)這個(gè)程序,清晰地掌握CICS實(shí)現(xiàn)三層C/S結(jié)構(gòu)的機(jī)制。之所以我把這個(gè)程序稱為EasyCICS的標(biāo)準(zhǔn)示例,是因?yàn)樗芯幊坦ぞ叩腅asyCICS演示程序都有這個(gè)稱為TELECOM的例子。那么,這個(gè)例子實(shí)現(xiàn)什么功能?TELECOM的客戶程序向服務(wù)程序提供一個(gè)移動(dòng)電話設(shè)備號(hào)碼,服務(wù)程序根據(jù)這個(gè)號(hào)碼查出相關(guān)的計(jì)費(fèi)單據(jù)后返回給客戶程序,客戶程序立即顯示此單據(jù)。整個(gè)過(guò)程都是在線同步執(zhí)行,這也是一個(gè)OLTP的典型例子。以下是C語(yǔ)言作的CICS服務(wù)程序的清單(注意,這個(gè)源程序可以不加修改的運(yùn)行在支持CICS的各種操作系統(tǒng)平臺(tái)上):/*/*- HEADER F

20、ILES -*/#include "easycics.h"/*/*- DEFINES -*/#ifdef _WIN32#define DLLIMPORT _declspec(dllimport)#define DLLEXPORT _declspec(dllexport)#define CDECL _cdecl#else#define DLLIMPORT#define DLLEXPORT#define CDECL#endif/* #define either ORA or DB2 here */#define DB2#define SQLNOTFOUND 100#if def

21、ined ( DB2 )#include <sql.h>#elif defined ( ORA )#define SQLNOTFOUND 1403#endif/*/*- Global Variables -*/EXEC SQL INCLUDE sqlca; EXEC SQL BEGIN DECLARE SECTION;char Usr_name61;char Dev_no9; long Call_flg; char Called_arno11;char Called_no15;char Call_dat21;double Call_dur; double Call_rate; do

22、uble Call_fee; double Add_fee;char as_dev_no9; EXEC SQL END DECLARE SECTION;/*/*Functions*/*/* */void GetValueNum(char *Key, char *Value, int Num)char s4096;GetValue( Key, s );strncpy(Value,s,Num);ValueNum-1 = '0'/* */void main()char statusbuf1024, s30;if( InitEasyCics() ) ExitEasyCics();/*R

23、ead:*/GetValueNum( "NO", as_dev_no, sizeof(as_dev_no) );/*Write:*/BeginWrite();SetValue( "VER", "Telecom 1.0");RsCreate(10);RsSetColNameList("Usr_name,Dev_no,Call_flg,Called_arno,Called_no,Call_dat,Call_dur,Call_rate,Call_fee,Add_fee");/*可省略*/EXEC SQL DECLARE

24、c1 CURSOR FOR SELECT bas_infot.Usr_name, auto10a_list.Dev_no, auto10a_list.Call_flg, auto10a_list.Called_arno, auto10a_list.Called_no, auto10a_list.Call_dat, auto10a_list.Call_dur, auto10a_list.Call_rate, auto10a_list.Call_fee, auto10a_list.Add_fee FROM auto10a_list, bas_infotWHERE ( auto10a_list.De

25、v_no = bas_infot.Dev_no ) AND auto10a_list.Dev_no = :as_dev_no;sprintf(statusbuf,"declear cursor code=%dn", sqlca.sqlcode);PrintStatus(statusbuf);EXEC SQL OPEN c1;sprintf(statusbuf,"open cursor code=%dn", sqlca.sqlcode);PrintStatus(statusbuf);doEXEC SQL FETCH c1 INTO :Usr_name, :

26、Dev_no, :Call_flg, :Called_arno, :Called_no, :Call_dat, :Call_dur, :Call_rate, :Call_fee, :Add_fee;sprintf(statusbuf,"fetch code=%dn", sqlca.sqlcode);PrintStatus(statusbuf);if( (sqlca.sqlcode = SQLNOTFOUND) | (sqlca.sqlcode <0) )break;elseRsAddRow();sprintf( statusbuf, "%s,%s,%d,%s

27、,%s,%s,%7.0f,%8.3f,%7.2f,%6.2fn", Usr_name, Dev_no, Call_flg, Called_arno, Called_no, Call_dat, Call_dur, Call_rate, Call_fee, Add_fee );PrintStatus(statusbuf);RsSetCol( 1, Usr_name );RsSetCol( 2, Dev_no );sprintf( s, "%lu", Call_flg );RsSetCol( 3, s );RsSetCol( 4, Called_arno );RsSet

28、Col( 5, Called_no );RsSetCol( 6, Call_dat );sprintf( s, "%6.2f", Call_dur );RsSetCol( 7, s );sprintf( s, "%6.2f", Call_rate );RsSetCol( 8, s );sprintf( s, "%6.2f", Call_fee );RsSetCol( 9, s );sprintf( s, "%6.2f", Add_fee );RsSetCol( 10, s );RsSaveRow();while(1

29、);EXEC SQL CLOSE c1; /*#ifdef( SYBASE )EXEC SQL DEALLOCATE CURSOR c1;#endif*/sprintf(statusbuf,"close cursor code=%dn", sqlca.sqlcode);PrintStatus(statusbuf);ExitEasyCics();清單 2-1-10 (telecom.sqc)這是個(gè)典型的E-SQL程序(在ORACLE中叫PROC),如果您不熟悉E-SQL編程,不用著急,本書有詳細(xì)的說(shuō)明。由于后面的內(nèi)容有對(duì)本程序的詳細(xì)分析,這里僅簡(jiǎn)要說(shuō)明一下程序的流程。如果不特

30、別注重程序的移植性、健壯性和調(diào)試信息,可以把清單2-1-10的程序簡(jiǎn)化成下面的程序:#include "easycics.h"#include <sql.h>#define SQLNOTFOUND 100EXEC SQL INCLUDE sqlca; EXEC SQL BEGIN DECLARE SECTION;char Usr_name61;char Dev_no9; long Call_flg; char Called_arno11;char Called_no15;char Call_dat21;double Call_dur; double Call_r

31、ate; double Call_fee; double Add_fee;char as_dev_no9; EXEC SQL END DECLARE SECTION;/* */void main()char s30;if( InitEasyCics() ) ExitEasyCics();/*Read:*/GetValue ( "NO", as_dev_no );/*Write:*/BeginWrite();RsCreate(10);RsSetColNameList("Usr_name,Dev_no,Call_flg,Called_arno,Called_no,Ca

32、ll_dat,Call_dur,Call_rate,Call_fee,Add_fee");/*可省略*/EXEC SQL DECLARE c1 CURSOR FOR SELECT bas_infot.Usr_name, auto10a_list.Dev_no, auto10a_list.Call_flg, auto10a_list.Called_arno, auto10a_list.Called_no, auto10a_list.Call_dat, auto10a_list.Call_dur, auto10a_list.Call_rate, auto10a_list.Call_fee

33、, auto10a_list.Add_fee FROM auto10a_list, bas_infotWHERE ( auto10a_list.Dev_no = bas_infot.Dev_no ) AND auto10a_list.Dev_no = :as_dev_no;EXEC SQL OPEN c1;doEXEC SQL FETCH c1 INTO :Usr_name, :Dev_no, :Call_flg, :Called_arno, :Called_no, :Call_dat, :Call_dur, :Call_rate, :Call_fee, :Add_fee;if( (sqlca

34、.sqlcode = SQLNOTFOUND) | (sqlca.sqlcode <0) )break;elseRsAddRow();RsSetCol( 1, Usr_name );RsSetCol( 2, Dev_no );sprintf( s, "%lu", Call_flg );RsSetCol( 3, s );RsSetCol( 4, Called_arno );RsSetCol( 5, Called_no );RsSetCol( 6, Call_dat );sprintf( s, "%6.2f", Call_dur );RsSetCol(

35、 7, s );sprintf( s, "%6.2f", Call_rate );RsSetCol( 8, s );sprintf( s, "%6.2f", Call_fee );RsSetCol( 9, s );sprintf( s, "%6.2f", Add_fee );RsSetCol( 10, s );RsSaveRow();while(1);EXEC SQL CLOSE c1; ExitEasyCics();清單 2-1-11 (簡(jiǎn)化telecom.sqc)清單2-1-11所示的程序可以用于CICS for NT,訪問(wèn)DB2

36、數(shù)據(jù)庫(kù)。我們來(lái)簡(jiǎn)單分析一下簡(jiǎn)化的telecom.sqc程序:這個(gè)程序采用的接口方法是EasyCICS,所以引入了“easycics.h”頭文件。 程序的開(kāi)始聲明了一些宿主變量(在EXEC SQL BEGIN DECLARE SECTION;和EXEC SQL END DECLARE SECTION;之間),所謂“宿主變量”即可以同時(shí)用于C語(yǔ)言變量和SQL變量。注意,以EXEC SQL打頭的語(yǔ)句都可以通過(guò)數(shù)據(jù)庫(kù)的預(yù)編譯程序轉(zhuǎn)化成相應(yīng)的C語(yǔ)言代碼。在執(zhí)行部分,程序首先調(diào)用InitEasyCics函數(shù)來(lái)初始化環(huán)境。接著調(diào)用GetValue函數(shù),此函數(shù)通過(guò)其參數(shù)指定的關(guān)鍵字“NO”來(lái)獲取客戶機(jī)方面通過(guò)

37、SetValue函數(shù)來(lái)設(shè)置的字符串值。再調(diào)用了BeginWrite函數(shù),表示開(kāi)始寫通信用的公共數(shù)據(jù)區(qū),它的真正作用是清除該公共數(shù)據(jù)區(qū)。接著調(diào)用了幾個(gè)以“Rs”為字頭的函數(shù),表示要設(shè)置結(jié)果集(ResultSet)。函數(shù)RsCreate表示要?jiǎng)?chuàng)建結(jié)果集,其參數(shù)是結(jié)果集的列數(shù)。函數(shù)RsSetColNameList設(shè)置結(jié)果集各列的名稱,如果客戶機(jī)僅通過(guò)相對(duì)位置來(lái)獲取各列的值(這樣效率更高),則可以省略此調(diào)用。接著程序聲明并打開(kāi)SQL游標(biāo),并在一個(gè)循環(huán)中不斷獲取數(shù)值存入宿主變量,直到游標(biāo)最后結(jié)束(sqlca.sqlcode=SQLNOTFOUND)或出錯(cuò)(sqlca.sqlcode <0)。注意每

38、從數(shù)據(jù)庫(kù)取出一行,調(diào)用RsAddRow函數(shù)使EasyCICS的結(jié)果集增加一行。取到宿主變量中的數(shù)值可以再通過(guò)RsSetCol函數(shù)寫到EasyCICS的結(jié)果集中,注意此函數(shù)的第一個(gè)參數(shù)是列序號(hào)(從1開(kāi)始),第二個(gè)參數(shù)是字符串值(EasyCICS只接受字符串值)。各列寫完之后,要調(diào)用RsSaveRow函數(shù)存儲(chǔ)此行數(shù)據(jù)。程序最后在關(guān)閉游標(biāo)后調(diào)用了ExitEasyCics函數(shù),注意在任何情況下退出CICS服務(wù)程序,必須調(diào)用該函數(shù)。只有C源程序還不夠,我們還需要把它編譯成執(zhí)行文件或庫(kù)文件(在Windows NT系統(tǒng),CICS服務(wù)程序最終要被編譯成為.DLL文件,即動(dòng)態(tài)連接庫(kù))。一些程序員習(xí)慣于使用集成編

39、譯工具,但無(wú)法使用在UNIX等操作系統(tǒng)。我們采用更加通用的makefile方式進(jìn)行編譯。以下是在NT系統(tǒng)中,編譯TELECOM服務(wù)程序的makefile(在各種UNIX系統(tǒng),要進(jìn)行必要的修改):all: telecom.dll telecom.ccs: telecom.sqcdb2 connect to cicstestdb2 prep telecom.sqc bindfiledb2 bind telecom.bnddb2 grant execute on package telecom to publicdb2 connect resetcopy telecom.c telecom.ccs

40、telecom.dll: telecom.ccsset CICS_MSC_FLAGS=-I$(DB2PATH)includeset USERLIB=$(DB2PATH)libdb2api.lib easycics.objcicstcl -e -d -lC telecom.ccsclean:del telecom.bnd telecom.c telecom.ccs telecom.dll telecom.exp telecom.lib telecom.obj清單 2-1-12再看看ANSI C的客戶程序,就是清單2-1-13展示的C程序。#include "ec.h"/* *

41、/void main()int i, j, rc, cc, r;char s100, c, cr;r= ConnectServer( "CICSNT01", "TEST", "TEST" );printf( "Connect Code: %dn", r );printf("Enter Query Number:");scanf( "%s", s );scanf( "%c", &cr );BeginWrite();SetValue( "NO

42、", s );r= CallProgramAndCommit("TELECOM");if(r)puts("Call Program Error !");return;RsOpen();rc = RsGetRowNum();cc = RsGetColNum();for( i=1; i<=rc; i+ )RsFetchRow(); for(j=1; j<cc; j+)RsGetCol(j,s);printf(s);printf( "," ); puts("");清單 2-1-13以下是運(yùn)行結(jié)果(按

43、提示輸入查詢的號(hào)碼,程序返回查詢的結(jié)果):D:cics>testecConnect Code: 0Enter Query Number:2020088宋阮,2020088,105011031,0595,01385995193,Apr 17 1999 10:55PM , 3.00, 1.00, 1.50,宋阮,2020088,105011031,0595,01385990145,Apr 16 1999 12:22PM , 1.00, 1.00, 1.00,宋阮,2020088,105011031,0595,01385922328,Apr 9 1999 6:42PM , 1.00, 1.00

44、, 1.00,宋阮,2020088,105011031,0595,01385922328,Apr 7 1999 12:50PM , 2.00, 1.00, 2.00,宋阮,2020088,105011031,0595,01385995193,Apr 6 1999 12:57PM , 3.00, 1.00, 3.00,宋阮,2020088,105011031,0595,01385995193,Apr 5 1999 11:29AM , 1.00, 1.00, 1.00,宋阮,2020088,105011031,0595,01385995193,Apr 5 1999 10:08AM , 1.00,

45、1.00, 1.00,宋阮,2020088,105011031,0595,01385995193,Apr 3 1999 3:50PM , 4.00, 1.00, 2.00,宋阮,2020088,105011031,0595,01385995183,Apr 3 1999 10:15AM , 1.00, 1.00, 0.50,宋阮,2020088,105011031,0595,01385995193,Mar 31 1999 9:48PM , 6.00, 1.00, 3.00,宋阮,2020088,105011031,0595,01385995193,Mar 29 1999 4:49PM , 5.0

46、0, 1.00, 5.00,宋阮,2020088,105011031,0595,01385995193,Mar 27 1999 3:03PM , 9.00, 1.00, 4.50,宋阮,2020088,105011031,0595,01385995193,Mar 21 1999 10:48PM , 3.00, 1.00, 1.50,清單 2-1-14這個(gè)程序采用的接口方法也是EasyCICS,所以我們引入了“ec.h”頭文件(注意服務(wù)程序使用的是叫做“easycics.h”的頭文件)。程序首先執(zhí)行了ConnectServer函數(shù)。該函數(shù)的第一個(gè)參數(shù)是CICS的系統(tǒng)名稱,相當(dāng)于CICS域(Reg

47、ion)的連接字符串;函數(shù)的后兩個(gè)參數(shù)分別是CICS的用戶名稱和口令。接著根據(jù)用戶輸入的號(hào)碼調(diào)用SetValue函數(shù),其作用是把一個(gè)字符串作為值賦予一個(gè)關(guān)鍵字(也是一個(gè)字符串),并存儲(chǔ)在公共數(shù)據(jù)區(qū)。在這里,”NO”是關(guān)鍵字。注意所謂關(guān)鍵字是用戶隨意定義的,但最好客戶程序和服務(wù)程序能相互匹配,如果沒(méi)有通過(guò)SetValue函數(shù)設(shè)置某關(guān)鍵字的值就直接調(diào)用GetValue函數(shù)取此關(guān)鍵字的值,則取出空字符串。再下面程序執(zhí)行了CallProgramAndCommit函數(shù),我們一般使用此函數(shù)來(lái)調(diào)用服務(wù)程序(Program)。該函數(shù)的唯一參數(shù)就是要調(diào)用的CICS的服務(wù)程序名稱,在此處,即TELECOM程序。接

48、下來(lái)程序調(diào)用了一些結(jié)果集函數(shù)(以“Rs”為字頭)。RsOpen函數(shù)用于打開(kāi)結(jié)果集。注意,RsCreate和RsOpen函數(shù)對(duì)是EasyCICS傳遞二維值的標(biāo)準(zhǔn)方法,而SetValue和GetValue函數(shù)對(duì)是EasyCICS傳遞單值(零維值)的標(biāo)準(zhǔn)方法。結(jié)果集的行數(shù)和列數(shù)可以通過(guò)函數(shù)RsGetRowNum 和RsGetRowNum得到。函數(shù)RsFetchRow用于取出結(jié)果集的一行,而函數(shù)RsGetCol用于取出當(dāng)前行的一列值。所有返回的值經(jīng)格式化后寫到屏幕上。這個(gè)客戶程序的makefile如下:all: testec.exetestec.exe: testec.objlink testec.o

49、bj ec.obj cclwin32.libtestec.obj: testec.ccl /c testec.c清單 2-1-15下面是Visual Basic客戶程序的源代碼:Option ExplicitDim oEc As New EasyCics.AppPrivate Sub btnAbout_Click() oEc.AboutEnd SubPrivate Sub btnQuery_Click()Dim r%, s$, i%, j%, rc%, cc% lstTest.Clear oEc.BeginWrite s = txtNo.Text oEc.SetValue "NO&q

50、uot;, s oEc.CallProgramAndCommit "TELECOM" s = oEc.GetErrIf s <> "" Then MsgBox "Got an error when call CICS Server program:" + Chr(13) + Chr(10) + s Exit SubEnd If oEc.RsOpen rc = oEc.RsGetRowNum cc = oEc.RsGetColNum s = ""For i = 1 To rc oEc.RsFetchRow

51、 For j = 1 To cc s = s + oEc.RsGetCol(j) + "," Next lstTest.AddItem s s = ""Next End SubPrivate Sub Form_Load()Dim r% r = oEc.ConnectServer("CICSNT01", "TEST", "TEST")If r <> 0 Then MsgBox "Can't connect" Exit SubEnd IfEnd SubPriv

52、ate Sub Form_Unload(Cancel As Integer) Set oEc = NothingEnd Sub清單 2-1-16Visual Basic程序采用EasyCICS組件(PowerBuilder和Delphi也是通過(guò)組件訪問(wèn)CICS)。使用面向?qū)ο蟮男g(shù)語(yǔ),我們將反復(fù)提到組件的“方法”,或接口的“方法”,而不能說(shuō)組件或接口的函數(shù)。程序預(yù)先創(chuàng)建了連接EasyCICS的對(duì)象。程序首先執(zhí)行了組件的ConnectServer方法。該方法的第一個(gè)參數(shù)是CICS的系統(tǒng)名稱,相當(dāng)于CICS域(Region)的連接字符串;函數(shù)的后兩個(gè)參數(shù)分別是CICS的用戶名稱和口令。接著根據(jù)用戶輸入的到文本框中的號(hào)碼調(diào)用了組件的SetValue方法,其作用是把一個(gè)字符串作為值賦予一個(gè)關(guān)鍵字(也是一個(gè)字符串),并存儲(chǔ)在公共數(shù)據(jù)區(qū)。在這里,”NO”是關(guān)鍵字。注意所謂關(guān)鍵字是用戶隨意定義的,但最好客戶程序和服務(wù)程序能相互匹配,如果沒(méi)有通過(guò)SetValue方法設(shè)置某關(guān)鍵字的值就直接調(diào)用GetValue

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論