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
{
char sqlcaid[8];
long sqlabc;
long sqlcode;
struct
{
int sqlerrml;
char sqlerrmc[SQLERRMC_LEN];
} sqlerrm;
char sqlerrp[8];
long sqlerrd[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的值变了!