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]; /*记录数*/
#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的列数与数组结构的列数一致。
这种用法比使用数组结构简单,但要求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程序的编译
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