这里假设用户的oracle已经安装完成了并且可以正确运行。
本文档包括fetch.pc,makefile,proc.txt 3个文件。
fetch.pc是proc源文件,详细注释在文件中。
makefile是make文件,目前我也不是很懂。
proc.txt就是本文件,主要说明环境配置。
可以用env|less查看当前用户的环境配置,注意看有没有以下2个:
LD_LIBRARY_PATH=$(ORACLE_HOME)/lib
PATH=$(ORACLE_HOME)/BIN
ORACLE_HOME=/opt/oracle/product/9.0.1
如果没有,可以用export命令加上。命令用法如下:
export LD_LIBRARY_PATH=$(ORACLE_HOME)/lib,为了保险起见,可以把$(ORACLE_HOME)用实际路径代替,如下:
export LD_LIBRARY_PATH=/opt/oracle/product/9.0.1/lib
同理加上PATH和ORACLE_HOME。注意,PATH中原来就有其他路径,应该把其他路径加上,否则会覆盖掉原来的路径。例如,原来PATH中有/usr/bin,则export命令应该这样:
export PATH=/opt/oracle/product/9.0.1/bin:/usr/bin
用:分号可以连接多个路径。
LD_LIBRARY_PATH没有的话会提示libclntsh.so.9.0文件或目录找不到。
ORACLE_HOME没有的话会提示PCC-F-NOERRFILE。
环境设置好以后,把fetch.pc,makefile放在同一目录下,执行make就行了。
在$(ORACLE_HOME)/precomp/lib/env_precomp.mk文件中,可能有/usr/lib/gcc-lib/i686-rpm-linux/2.95.3/include,这个路径中的文件与实际环境中的文件不一致的情况,要注意修改。在$(ORACLE_HOME)/precomp/admin/pcscfg.cfg中也有相同的地方要注意。
pro c 中sqlstm.stmt的传递(参考TKL000L)
有一段代码如下。
EXEC SQL DECLARE CUR_INET CURSOR FOR
SELECT LPAD(TO_CHAR(ZZZ_JIMUCD),2,'0'),LPAD(TO_CHAR(COUNT(ZZZ_JIMUCD)),6,' ')
FROM VRKAIMST
WHERE ZZZ_KAIINNO<=999999 AND ZZZ_DELKBN=' ' AND
(TO_DATE(:szDate,'YYYYMMDD') BETWEEN
(TO_DATE(TO_CHAR(ZZZ_STAYY,'0000')||TO_CHAR(ZZZ_STAMM,'00')||TO_CHAR(ZZZ_STADD,'00'), 'YYYYMMDD')) AND
(TO_DATE(TO_CHAR(ZZZ_ENDYY,'0000')||TO_CHAR(ZZZ_ENDMM,'00')||TO_CHAR(ZZZ_ENDDD,'00'), 'YYYYMMDD')))
GROUP BY ZZZ_JIMUCD;
这时候,执行打开游标的操作EXEC SQL OPEN CUR_INET;出错,那么程序跳转到错误处理fn_SqlAccessError(sqlstm.stmt)。
EXEC SQL WHENEVER SQLERROR DO fn_SqlAccessError(sqlstm.stmt);
EXEC SQL OPEN CUR_INET;
EXEC SQL WHENEVER NOT FOUND DO break;
void fn_SqlAccessError(char *pSqlStmt)
{
printf("sql:%s/n",pSqlStmt);
}
如果不传递参数,那么,在错误处理函数中就输出sqlstm.stmt为null,传递参数后就输出实际的select语句.原因是:
上面的select语句,在pro c中编译成c语言后,是这个形式:
{
......
sqlstm.stmt=sql0003;
......
if (sqlca.sqlcode < 0) fn_SqlAccessError(sqlstm.stmt);
}
这段语句有大括号,出了大括号,sqlstm.stmt就为null,所以必须要赋值.
或者用另一种方法:
void fn_SqlAccessError()
{
char stmt[1000];
size_t sqlfc,stmtlen=1000;
unsigned int i;
i=sqlgls(stm,&stmtlen,&sqlfc);
/* 显示出错语句*/
printf("sql:%.*s/n",stmtlen,stmt);
/*显示错误信息*/
printf("error:%.*s/n",sqlca.sqlerrm.sqlerrml,sqlca.sqlerrm.sqlerrmc);
}
fetch.pc
#include <stdio.h>
EXEC SQL INCLUDE sqlca;
EXEC SQL INCLUDE oraca;
EXEC SQL BEGIN DECLARE SECTION;
char username[] ="MDUSR";
char password[] ="MDUSR";
char db_name[] ="MDUSR";
int testId;
char testStr[32];
EXEC SQL END DECLARE SECTION;
char temp[32];
void sql_error();
int main(int argc,char *argv[])
{
EXEC SQL WHENEVER SQLERROR do sql_error("Oracle error");
EXEC SQL CONNECT :username IDENTIFIED BY :password USING :db_name;
printf("Connected./n");
EXEC SQL DECLARE TESTCURSOR CURSOR FOR
SELECT HIDUKE FROM TK01 ;
EXEC SQL OPEN TESTCURSOR;
EXEC SQL WHENEVER NOT FOUND DO break;
while(1)
{
printf("test string is --> ");
EXEC SQL FETCH TESTCURSOR INTO :testStr;
printf("%s /n ", testStr);
}
EXEC SQL CLOSE TESTCURSOR;
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}
void sql_error(char *msg)
{
char buf[500];
int buflen, msglen;
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK WORK RELEASE;
printf("sqlcode:<%d>/n", sqlca.sqlcode) ;
printf("sqlca.sqlerrm.sqlerrmc:%s/n",sqlca.sqlerrm.sqlerrmc) ;
buflen = sizeof (buf);
sqlglm(buf, &buflen, &msglen);
printf("%s /n", msg);
printf("%*.s /n", msglen, buf);
exit(1);
}
makefile
#include /opt/oracle/product/9.0.1/precomp/lib/env_precomp.mk
PROC=/opt/oracle/product/9.0.1/bin/proc
GCC=$(CC)
BINDIR=$(HOME)/bin
ORAIFLAG=-I/opt/oracle/product/9.0.1/rdbms/public -I/opt/oracle/product/9.0.1/rdbms/demo -I/opt/oracle/product/9.0.1/precomp/public -I/opt/oracle/product/9.0.1/plsql/public
ORALFLAG=-L/opt/oracle/product/9.0.1/lib -L/opt/oracle/product/9.0.1/precomp/lib -L/opt/oracle/product/9.0.1/rdbms/lib -L/opt/oracle/product/9.0.1/sqlplus/lib -L/opt/oracle/product/9.0.1/network/lib -L/opt/oracle/product/9.0.1/plsql/lib
IFLAG=-I$(HOME)/include $(ORAIFLAG)
LFLAG=-L$(HOME)/lib $(ORALFLAG) -lclntsh
PROCFLAGS=char_map=string
.SUFFIXES: .pc .c .o
.pc.c:
$(PROC) $(PROCFLAGS) iname=$*
#rm *.lis
.pc.o:
$(PROC) $(PROCFLAGS) iname=$*
#rm *.lis
$(GCC) $(IFLAG) -c $*.c
.c.o:
$(GCC) $(IFLAG) -c $*.c
all:fetch
fetch:fetch.o
$(GCC) $? -o $@ $(LFLAG)
# @echo "##### $@ loaded #####"