程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Pro*C 程序編程(包括數組的使用)

Pro*C 程序編程(包括數組的使用)

編輯:關於C語言
 

用Pro*C編寫程序與在PB中直接用SQL語句類似,在PB中能用的SQL語法在Pro C中同樣適用,數據庫能用的函數也都可以使用,所有的SQL語句都應符合Oracle的語法,只是多一些C語言中的語法和限制,

/*********************************************下面是一個最簡單的例子:
/*程序開始,有一些需要包含的.H文件*/
#include <stdio.h>
#ifdef _WIN32
#define DLLIMPORT __declspec(dllimport)
#define DLLEXPORT __declspec(dllexport)
#define CDECL __cdecl
#else
#define DLLIMPORT
#define DLLEXPORT
#define CDECL
#endif
#define SQLCA_STORAGE_CLASS extern
/*SQL沒有記錄的返回值*/
#define SQLNOTFOUND 1403
/*Pro C必須在每一個程序中寫的語句,SQLCA的大小寫必須所有程序一致*/
EXEC SQL INCLUDE SQLCA;
EXEC ORACLE OPTION (RELEASE_CURSOR = YES); /*該語句可以在Makefile中寫*/
/*有了下面的定義,就不需要進行變量類型的等價了VAR IS STRING()*/
EXEC ORACLE OPTION (CHAR_MAP = STRING); /*該語句可以在Makefile中寫*/
void main()
{
/*聲明需要在SQL語句中使用的變量,這些變量在非SQL中也能使用*/
EXEC SQL BEGIN DECLARE SECTION;
char szCodeName[41] = ""; /*CHAR變量的長度必須比數據庫中大1*/
/*對VARCHAR類型必須進行等價說明,否則可能有空格,或設置CHAR_MAP=STRING*/
EXEC SQL VAR szCodeName IS STRING(41);
/*指示變量,必須是short int 類型,*/
short int indCodeName = 0;
/*與EXEC SQL BEGIN DECLARE SECTION;成對使用*/
EXEC SQL END DECLARE SECTION;
/*也可以不需要EXEC SQL BEGIN /END DECLARE SECTION;,在編譯上控制*/
strcpy(szConnectString,"jifei/jifei@jifei");
/*連接數據庫*/
EXEC SQL connect :szConnectString;
/*或EXEC SQL CONNECT :szUser IDENTIFIED BY :szPassword using :szDBString;*/
if (sqlca.sqlcode !=0) /*判斷SQL語句是否執行成功*/
{
printf("Connect Error , Error Message : %s\n",sqlca.sqlerrm.sqlerrmc);
exit(0);
}
EXEC SQL select code_name into :szCodeName
from CODE_NAME where rownum = 1;
if (sqlca.sqlcode < 0) /*判斷SQL語句是否執行成功*/
{
printf("Connect Error , Error Message : %s\n",sqlca.sqlerrm.sqlerrmc);
EXEC SQL rollback work release;
exit(0);
}
if (sqlca.sqlcode == SQLNOTFOUND) /*沒有結果,必須用SQLNOTFOUND,不要直接用1403*/
{
printf("No Data to Fetch\n");
EXEC SQL rollback work release;
exit(0);
}
printf("Code_Name = %s.\n",szCodeName);
/*提交並斷開連接*/
EXEC SQL commit work release;
}

 

/**************************************************一些基本的用法:

1、VARCHAR2型變量的數據定義

如果數據庫中是varchar2型的字段,在Pro*C中類型定義成char szFieldName[n+1]

如果在Makefile文件中的預編譯參數中char_map=STRING則不需要進行類型等價,否則需要進行字符類型的等價定義:

EXEC SQL VAR szFieldName IS STRING(n+1);

如不進行等價,則變量用空格填充。

2、判斷NULL值的方法

在Pro* C中,如某一個字段是NULL值,sqlca.sqlcode是小於0的,所以對可能出現NULL的列在into 語句中用指示變量則sqlca.sqlcode = 0,這時指示變量= -1

EXEC SQL select col1 into :nCol1 :indCol1 ......

if (indCol1 == -1) /*Col1為NULL,必須處理*/

{ nCol1 = 0;

}

注意 :nCol1:indCol1之間沒有“,”號

3、錯誤處理的方法

在Pro*C中可以對每一條語句判斷其sqlca.sqlcode來做錯誤判斷,也可以用類型Oracle的異常處理的方式:

EXEC SQL WHENEVER SQLERROR goto Error_Exit;

Error_Exit:

EXEC SQL WHENEVER SQLERROR continue; /*停止錯誤處理*/

exec sql rollback;

gf_PrintMess("提款反銷失敗:Point = %d",iBKPoint);

#ifdef _DEBUG_

gf_PrintMess("SQL = %s",szSQL);

#endif

gf_PrintMess("=========提款反銷====Error");

cics_return(-1,ERROR_DB,sqlca.sqlcode,sqlca.sqlerrm.sqlerrmc);

return;

對其他錯誤也能進行異常處理定義,如 NOT FOUND,不過,一般不這樣做。這樣所有的SQL語句後會自動判斷sqlca.sqlcode是否小於0,如小於0則goto Error_Exit。在C語句中是不建議用goto語句的,所以如果一個程序只有一種錯誤處理方式,即只要出錯就返回這麼用也是很方便、很直觀的。

4、結構在SQL語句種的使用

對定義的結構,如與查詢的結果列一致,可以直接使用,如

select a1,a2 into :str_a1a2……

5、數組在SQL語句中的使用:

a、FETCH Cursor中的使用

#define MAX_ACCT_ROWS 10000 /*定義每次處理的用戶數=1萬*/

struct _AcctFund{

ulong ulAcctID[MAX_ACCT_ROWS]; /*付費編號*/

long lBalance[MAX_ACCT_ROWS]; /*存款余額*/

VARCHAR szRowID[MAX_ACCT_ROWS][20]; /*ACCT_FUND中的ROWID*/

} astrAcctFund;


EXEC SQL FOR :MAX_ACCT_ROWS FETCH Cur_fund INTO

:astrAcctFund.ulAcctID,

:astrAcctFund.lBalance,

:astrAcctFund.szRowID[0];

iRows_fund = sqlca.sqlerrd[2]; /*記錄數*/

b、Insert 中使用

int nID[100] ;

EXEC SQL FOR 100 insert into t_a values (:nID);

c、Where 中使用

int nID[100];

EXEC SQL for 100 delete from t_a where id = :nID;

d、動態語句中使用

int nID[100];

strcpy(szSql,”insert into t_a values(:v1)”);

EXEC SQL PREPARE st_EXE_Sql FROM :szSql;

EXEC SQL FOR 100

EXECUTE st_EXE_print using :nID;

 

e、結構數組的使用

struct _S_TYPE {

int nCodeId;

char szCodeName[41];

}s_Type[100];

_S_TYPE *psType = &s_Type[0]; /*必須定義一個指針*/

EXEC SQL for 100

select code_id,code_name into :psType

from CODE_ID_NAME where rownum <= 100;


這種用法比使用數組結構簡單,但要求select的列數與數組結構的列數一致。


6、Pro C中使用存儲過程

EXEC SQL EXECUTE

BEGIN

up_db_pay_open(:iPartID,:aszAcctID,0,1,:aszOperSerialNbr,

:aszStaffID,2,:iPartOpen,:aszOweState,

:iErrPB,:lErrSys,:szErrSysMsg);

END;

END-EXEC;


7、Pro C程序的編譯
#####################################

proc.mk,Pro C程序的編譯 Makefile,makefile

make

test1.mk

make –f test1.mk [test1]

#####################################

#ORACLE_HOME = /oracle/app/oracle/product/8.0.6
PROC_PL = $(ORACLE_HOME)/bin/proc parse=FULL release_cursor=no USERID=bill/AC6C69626 sqlcheck=SEMANTICS char_map=STRING ireclen=512 iname=

#如果在Pro*C中沒有使用存儲過程,SQLCHECK可以等於syntax
CCFLAGS = -L$(ORACLE_HOME)/lib -lclntsh -lm -lld -D_DEBUG_
COMPILE = xlc_r4 -c $(CICSFLAGS) $(CCFLAGS) -o

.SUFFIXES: .pc .c .o

.pc.c:
$(PROC_PL) $<

.c.o:
$(CC) $(CCFLAGS) -c $<

.pc.o:
$(PROC_PL) $<
$(CC) $(CFLAGS) -c $(<:.pc=.c)

test : test.o fbillpub.o
$(COMPILE) test.o –o test

 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved