這裏假設用戶的oracle已經安裝完成了並且可以正確運行。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
本文檔包括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 #####"