我經常聽一些人大談把兩層CS結構的應用轉為三層CS結_第1頁
我經常聽一些人大談把兩層CS結構的應用轉為三層CS結_第2頁
我經常聽一些人大談把兩層CS結構的應用轉為三層CS結_第3頁
我經常聽一些人大談把兩層CS結構的應用轉為三層CS結_第4頁
我經常聽一些人大談把兩層CS結構的應用轉為三層CS結_第5頁
已閱讀5頁,還剩96頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第二章 編程我經常聽一些人大談把兩層C/S結構的應用轉為三層C/S結構的應用,無論說的,還是聽的,都興高采烈,頻頻點頭:好,好!轉吧。不過,具體怎么“轉”呢?是不是把兩層C/S結構的程序放到什么容器里“煮”一下,再取出來就可以“吃”了?當然不行,看來一個“轉”字還頗有點兒學問。如果您原來靠游泳過河,那我教您一種劃船過河的方法,這條船就是中間件CICS當然您不能靠劃船的經驗來驅動它,CICS需要的是編程。學劃船很簡單,學CICS編程也一樣簡單,讀了本章的內容就會知道。如果讀者想用COBOL或JAVA來開發CICS的服務程序,請參閱CICS的其它技術資料,這里只提供了C語言的例子。不過,這里提供了

2、幾乎所有常用的前端開發工具作為CICS客戶的例子,也許這正是您所需要的,那么,請認真閱讀后面的內容。如果您已經有足夠多的預備知識,可以先閱讀下一章,在建好一個實驗環境后,再回到本章。2.1 建立一個簡單的CICS應用CICS程序:GETTIME我們將要看到的這個CICS程序基本沒有用到CICS強大的事務處理監控能力,所以更象是一個兩層C/S的應用。但是因為它如此簡單,我還是把它做為您學習CICS的入門程序。做過UNIX或NT的服務程序(UNIX經常叫DAEMON程序)朋友,會發現CICS服務程序非常容易實現,因為您不必去處理Socket、Named Pipe或FIFO之類的東西。是的,如果不考

3、慮價格因素,用CICS去實現許多一般的服務程序可是個省事的好辦法。設想某公司要投資開發一個叫GETTIME的服務程序,其功能是公布服務器的時間,供他們的各種前端客戶程序使用。這些程序必須能運行于各種常用的UNIX平臺和WINDOWS NT,甚至可以移植到AS400和IBM大型機上。正在公司的編程高手們紛紛摩拳擦掌,準備大干一場時,一個初級的CICS程序員突然宣布他已在5分鐘內完成了任務,并將得到一筆可觀的報酬有這種好事嗎?那我們不妨就來看看GETTIME的CICS解決方案。這是C語言作的CICS服務程序的清單(注意,這個源程序可以不加修改的運行在支持CICS的各種操作系統平臺上):#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)客戶程序更加簡單,下面是一些例子:1、ANSI C的客戶程序見清單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以下是運行結果:D:cics>gett

6、imeThu Jan 27 17:35:14 2000清單 2-1-32、使用OLE可以支持Windows上的各種開發工具,例如: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以下是運行結果:圖 2-1-13、如果使用JAVA,可以無須重新編譯地移植您的程序。下面是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以下是運行結果:D:cics>java GetTimeSat Jan 29 21:22:16 2000清單 2-1-7我還能羅列出一大堆編程工具訪問CICS的源碼,是的,它們非常類似。您可能

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

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

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

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

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

14、ue函數來設置的字符串值。注意,可以通過多個SetValue和GetValue函數來傳遞多個字符串值。另外,如果客戶機方面調用SetValue函數,而服務器方面調用GetValue函數也完全可以。SetValue和GetValue函數對是EasyCICS傳遞值的標準方法之一。這個客戶程序的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展示的程序。這個程序采用EasyCICS組件。使用面向對象的術語,我們將反復提到組件的“方法”,或接口的“方法”,而不能說組件或接口的函數。程序在A處調用了VB的函數CreateObject創建了連接EasyCICS的對象。程序在B處執行了組件的ConnectServer方法。該方法的第一個參數是CICS的系統名稱,相當于CICS域(Region)的連接字符串;函數的后兩個參數分別是CICS的用戶名稱和口令。程序在C處執行了組件的CallProgramAndCommit方法,我們一般使用此函數來調用服務程序(Program)。該函數的唯一參數就是要調用的CICS的服務程序名稱

16、,在此處,即GETTIME程序。程序在D處執行了組件的GetValue方法,此函數通過其參數指定的關鍵字來獲取服務器方面通過SetValue函數來設置的字符串值。注意,可以通過多個SetValue和GetValue函數來傳遞多個字符串值。另外,如果客戶機方面調用SetValue函數,而服務器方面調用GetValue函數也完全可以。SetValue和GetValue函數對是EasyCICS傳遞值的標準方法之一。Visual Basic不需要makefile之類的東西,可見使用組件是多么的簡單。我們在PowerBuilder和Delphi中,都是通過組件訪問CICS。最后,我們研究一下JAVA的例

17、子。JAVA通過GateWay來訪問CICS Client,我們也可以采用EasyCICS,所以,我們首先引入了easycics.*,這為我們訪問CICS Client奠定了基礎。程序在A處創建了easycics.App的類實例對象。程序在B處執行了類的ConnectServer方法。該方法的第一個參數是CICS的系統名稱,相當于CICS域(Region)的連接字符串;函數的后兩個參數分別是CICS的用戶名稱和口令。程序在C處執行了類的CallProgramAndCommit方法,我們一般使用此函數來調用服務程序(Program)。該函數的唯一參數就是要調用的CICS的服務程序名稱,在此處,即

18、GETTIME程序。程序在D處執行了類的GetValue方法,此函數通過其參數指定的關鍵字來獲取服務器方面通過SetValue函數來設置的字符串值。注意,可以通過多個SetValue和GetValue函數來傳遞多個字符串值。另外,如果客戶機方面調用SetValue函數,而服務器方面調用GetValue函數也完全可以。SetValue和GetValue函數對是EasyCICS傳遞值的標準方法之一。JAVA也不需要makefile之類的東西,而且可以不用重新編譯,就移植到各種操作系統平臺上。也許您對對上面介紹的示例程序GETTIME不以為然,因為它太簡單了。那么,下面將介紹另一個示例程序TELEC

19、OM,一個同樣簡單但功能健全的標準示例程序。您可以通過這個程序,清晰地掌握CICS實現三層C/S結構的機制。之所以我把這個程序稱為EasyCICS的標準示例,是因為所有編程工具的EasyCICS演示程序都有這個稱為TELECOM的例子。那么,這個例子實現什么功能?TELECOM的客戶程序向服務程序提供一個移動電話設備號碼,服務程序根據這個號碼查出相關的計費單據后返回給客戶程序,客戶程序立即顯示此單據。整個過程都是在線同步執行,這也是一個OLTP的典型例子。以下是C語言作的CICS服務程序的清單(注意,這個源程序可以不加修改的運行在支持CICS的各種操作系統平臺上):/*/*- 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)這是個典型的E-SQL程序(在ORACLE中叫PROC),如果您不熟悉E-SQL編程,不用著急,本書有詳細的說明。由于后面的內容有對本程序的詳細分析,這里僅簡要說明一下程序的流程。如果不特

30、別注重程序的移植性、健壯性和調試信息,可以把清單2-1-10的程序簡化成下面的程序:#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 (簡化telecom.sqc)清單2-1-11所示的程序可以用于CICS for NT,訪問DB2

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

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

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

39、譯工具,但無法使用在UNIX等操作系統。我們采用更加通用的makefile方式進行編譯。以下是在NT系統中,編譯TELECOM服務程序的makefile(在各種UNIX系統,要進行必要的修改):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以下是運行結果(按

43、提示輸入查詢的號碼,程序返回查詢的結果):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這個程序采用的接口方法也是EasyCICS,所以我們引入了“ec.h”頭文件(注意服務程序使用的是叫做“easycics.h”的頭文件)。程序首先執行了ConnectServer函數。該函數的第一個參數是CICS的系統名稱,相當于CICS域(Reg

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

48、下來程序調用了一些結果集函數(以“Rs”為字頭)。RsOpen函數用于打開結果集。注意,RsCreate和RsOpen函數對是EasyCICS傳遞二維值的標準方法,而SetValue和GetValue函數對是EasyCICS傳遞單值(零維值)的標準方法。結果集的行數和列數可以通過函數RsGetRowNum 和RsGetRowNum得到。函數RsFetchRow用于取出結果集的一行,而函數RsGetCol用于取出當前行的一列值。所有返回的值經格式化后寫到屏幕上。這個客戶程序的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也是通過組件訪問CICS)。使用面向對象的術語,我們將反復提到組件的“方法”,或接口的“方法”,而不能說組件或接口的函數。程序預先創建了連接EasyCICS的對象。程序首先執行了組件的ConnectServer方法。該方法的第一個參數是CICS的系統名稱,相當于CICS域(Region)的連接字符串;函數的后兩個參數分別是CICS的用戶名稱和口令。接著根據用戶輸入的到文本框中的號碼調用了組件的SetValue方法,其作用是把一個字符串作為值賦予一個關鍵字(也是一個字符串),并存儲在公共數據區。在這里,”NO”是關鍵字。注意所謂關鍵字是用戶隨意定義的,但最好客戶程序和服務程序能相互匹配,如果沒有通過SetValue方法設置某關鍵字的值就直接調用GetValue

溫馨提示

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

評論

0/150

提交評論