PRO*C无法连接Oracle数据库实例orclpdb1问题求助
无法通过PRO*C代码连接Oracle数据库实例orclpdb1,调试发现程序连接的是不存在的数据库名称。日志显示用户名和密码为null,当前数据库为32c(预期应为orclpdb1),schema下表数量为0,需排查问题。
Svc_Login函数代码
void Svc_Login() { varchar orauid[ USER_ID_SIZE ]; varchar oraupw[ PASSWORD_SIZE ]; int table_count=0; char curr_schema[20]; char curr_db[20]; char str_user_id[20]; char str_user_pw[20]; /*TDT,II - 02 May 2006 - Added Level 1 Debugging */ if ( iDebug >= 1 ) WriteTrace( "Running Svc_Login" ); orauid.len = sprintf( orauid.arr, "item" ); oraupw.len = sprintf( oraupw.arr, "item" ); EXEC SQL CONNECT :orauid IDENTIFIED BY :oraupw; EXEC SQL select user into :curr_schema from dual; sprintf( cLogText, "Connecting with username %s and password %s",VARCHAR2CHAR(str_user_id, orauid),VARCHAR2CHAR(str_user_pw,oraupw)); WriteTrace(cLogText); EXEC SQL select ora_database_name into :curr_db from dual; sprintf( cLogText, "The current db is %s", curr_db ); WriteTrace(cLogText); EXEC SQL select count(*) into :table_count from tab; sprintf( cLogText, "The No.of Tables in %s schema is ~%d~", curr_schema,table_count ); WriteTrace(cLogText); return; /* return to mainline code */ } #define VARCHAR2CHAR(a,b) (strncpy(a, (char*)b.arr, b.len), a[b.len] = '\0')
环境配置脚本
#!/bin/ksh # Set Oracle environment up first # Set Path and Oracle environment VERSION=`uname -v` RELEASE=`uname -r` export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1 export ORACLE_SID=orclpdb1 export PATH=$PATH:$ORACLE_HOME/bin export WAUUSER=item export WAUPASSW=item export ITEMUSER=item export ITEMPASSW=item
调试日志
oracle@azureRHEL MenuPrograms]$ cd /opt/cao/logs/ [oracle@azureRHEL logs]$ cat caoforms.trc.log 04:40:19: Setting Debug Level to ~2~ 04:40:19: Running Svc_Login 04:40:21: Connecting with username (null) and password (null) 04:40:21: The current db is 32c 04:40:21: The No.of Tables in k schema is ~0~ 04:40:29: Running SecurityEnterKey 04:40:29: orLoginInfo.user_id_count value is ~0~ 04:40:29: MAHESH 04:40:29: 04:40:31: Running wrap_up [oracle@azureRHEL logs]$
排查分析与解决建议
1. 日志中用户名/密码显示为null的问题
当前VARCHAR2CHAR宏使用逗号表达式,返回值是最后一个表达式a[b.len] = '\0'的结果(即ASCII 0),被sprintf当作空指针处理,导致日志显示null。实际代码中的orauid和oraupw赋值是正确的,仅日志打印逻辑有误。
修复宏定义,让其返回目标字符串数组:
#define VARCHAR2CHAR(a,b) (strncpy(a, (char*)b.arr, b.len), a[b.len] = '\0', a)
2. 连接到错误数据库(显示32c而非orclpdb1)
ora_database_name返回的是CDB(容器数据库)的名称,而非PDB(可插拔数据库)。PRO*C默认通过ORACLE_SID连接实例,但19c中PDB需要通过服务名指定连接。
修改CONNECT语句,添加USING子句指定PDB服务名:
EXEC SQL CONNECT :orauid IDENTIFIED BY :oraupw USING 'orclpdb1';
确保数据库监听已配置orclpdb1服务名,也可使用EZCONNECT格式:'//localhost:1521/orclpdb1'。
3. Schema下表数量为0及curr_schema乱码问题
curr_schema被定义为char类型,PRO*C绑定char数组时未自动添加字符串结束符,导致获取的用户名出现乱码。同时,当前连接的是CDB根容器,item用户可能不存在于该容器,或无任何表。
将curr_schema改为PRO*C的varchar类型,再转换为char:
varchar curr_schema[20]; char curr_schema_char[20]; // ... EXEC SQL select user into :curr_schema from dual; VARCHAR2CHAR(curr_schema_char, curr_schema); // 后续日志打印使用curr_schema_char sprintf( cLogText, "The No.of Tables in %s schema is ~%d~", curr_schema_char, table_count );
4. 环境变量验证
确认环境脚本中的ORACLE_HOME路径正确,ORACLE_SID在19c中通常对应CDB实例,连接PDB的核心是CONNECT语句中的服务名配置。
内容的提问来源于stack exchange,提问作者Mahesh Babu Tatineni

