1. 程式人生 > >oracle pro*c 64位系統開發的幾個坑

oracle pro*c 64位系統開發的幾個坑

1、首先,在32位系統下開發,遠端連線32位oracle伺服器,pro*c的select和fetch都沒問題,正常。

2、預編譯的坑。遷移到64位系統,把oracle開發客戶端從11升級到12,發現預編譯proc命令,編譯不過了,查找了一番,原因是安裝oracle客戶端的使用者和屬組,跟開發執行預編譯命令的使用者不符合,把執行預編譯命令的使用者改成用oracle使用者屬組來執行,就行了。

具體錯誤是:

命令:./make_pc.sh

報錯:

dbgc_init_all failed with ORA-48141
ORA-00600: internal error code, arguments: [17998], [2], [], [], [], [], [], [], [], [], [], []
ORA-00600: internal error code, arguments: [17998], [2], [], [], [], [], [], [], [], [], [], []




----- Call Stack Trace -----
calling              call     entry                argument values in hex      
location             type     point                (? means dubious value)     
-------------------- -------- -------------------- ----------------------------
skgudmp()+188        call     kgdsdst()            000000000 ? 000000000 ?
                                                   000000000 ? 000000000 ?
                                                   000000000 ? 000000000 ?
kgeriv_int()+191     call     skgudmp()            000000000 ? 000000000 ?

3、sqlca.sqlcode的坑!改成開發伺服器是64位,下載了64位oracle客戶端安裝上,配置好makefile,但是連線的oracle是32位,(不知道是不是位數不匹配這個問題),然後把.pc檔案預編譯好,生成.cpp檔案。再把工程編譯一下,沒問題。

執行時發現 sqlca.sqlcode在沒找到資料的時候會出錯!

例如:

EXEC SQL select CLASSNAME into :szCn from CLASSES where id = 1000;    //1000這個id是不存在的
    if (sqlca.sqlcode == 0)  
    {  

    }  
    else
    {
    printf("資料庫select錯誤(%d),%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
    }

列印的結果是:資料庫select錯誤(1380909089), 未找到任何資料

如果把 printf("資料庫select錯誤(%d),%s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);  的%d改成 %ld,列印的一串大資料,也根本不是預想的1403.

最坑的是,會影響後續的disconnect操作,還會影響下次繼續connect到oracle,登陸失敗。

解決方法是:不要相信預編譯proc生成的.cpp檔案!!把.cpp檔案的

struct sqlca_t
{
charsqlcaid[8];
longsqlabc;
longsqlcode;
struct
{
intsqlerrml;
charsqlerrmc[SQLERRMC_LEN];
}sqlerrm;
charsqlerrp[8];
longsqlerrd[6];

。。。

}

結構體的long改成int型!64位系統的問題,我以為oracle的64位開發庫會解決好,誰知道留這麼一個大坑。(暫時發現可以這樣解決,具體還有什麼更好的方法,以後再看)

4、fetch的坑!fetch完所有資料,sqlca.sqlcode等於1403,但是!緊接著讀取這個sqlca.sqlcode的時候,這個值就變成0了!!!簡直了!

if(1403 == sqlca.sqlcode)
{
 iSqlcode=sqlca.sqlcode;
printf("資料庫fetch遊標讀取完了(%d)(%d),%s\n",  iSqlcode,sqlca.sqlcode,  sqlca.sqlerrm.sqlerrmc);
EXEC SQL CLOSE C1;
}
else if(0 != sqlca.sqlcode)
{
iSqlcode=sqlca.sqlcode;
printf("資料庫fetchArchivedLog錯誤(%d)(%d),%s,%s\n",
iSqlcode, sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc,sqlca.sqlerrp);
EXEC SQL CLOSE C1;
}
else
{
iSqlcode=sqlca.sqlcode;
setValues();
}
printf("資料庫fetchArch返回值(%d)(%d)\n",iSqlcode,sqlca.sqlcode);

return iSqlcode;   //之前是return sqlca.sqlcode,被坑慘......

結果是這樣的:

資料庫fetchArchivedLog遊標讀取完了(1403)(1403),A-01403: 未找到任何資料  
                                     
資料庫fetchArchivedLog返回值(1403)(0)

----------------------------------------------------------------------------------------------------------

看到上面的返回值列印的時候,sqlca.sqlcode的值變了!