linux oracle proc 配置文件,Oracle数据库开发(二).Linux下配置使用ProC

一、提要

上文简单介绍了Windows下ProC配置开发,这次我们使用Linux平台再次配置Oracle ProC开发环境(RedHat Linux 9 + Oracle 92)。

《ORACLE数据库开发(一).Windows下配置使用ProC》和《ORACLE数据库开发(二).Linux下配置使用ProC》这两篇文章的目的只是做一些基础介绍,至于Oracle ProC编译参数以及Linux下的ProC Makefile

相关内容,将再后续文章逐步引入。

一言以弊之,先易后难。

二、数据库环境

与Windows下十分类似,首先确认安装了组件,Oracle - Application Development - Pro C-C++ 。安装后会在\$ORACLE_HOME/bin生成相应可执行文件,在\$ORACLE_HOME/precomp/demo/proc下也会生成一些makefile文件和示例。

三、示例文件

main.pc

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

#include "sqlca.h"

#include

#include

#include

void sql_error(char *msg)

{

printf("n%s %sn", msg,(char *)sqlca.sqlerrm.sqlerrmc);

EXEC SQL ROLLBACK RELEASE;

exit(0);

}

int main() {

EXEC SQL INCLUDE sqlca;

EXEC ORACLE OPTION (RELEASE_CURSOR = YES);

EXEC SQL WHENEVER SQLERROR DO sql_error(" ");

EXEC SQL BEGIN DECLARE SECTION;

VARCHAR oraCN[30];

EXEC SQL END DECLARE SECTION;

strcpy(oraCN.arr,"system/manager@linuxdb");

oraCN.len = strlen(oraCN.arr);

oraCN.arr[oraCN.len]='';

EXEC SQL CONNECT :oraCN;

printf("n [OK Connected!] ");

return 0;

}

代码其实是Windows的原版。

四、编译运行

无需修改任何参数文件,即安装后直接创建main.pc,执行如下命令:

\$ proc parse=none iname=main.pc

Pro*C/C++: Release 9.2.0.4.0 - Production on Thu Jun 7 14:17:05 2007

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

System default option values taken from: /home/ora/ora9/oracle/precomp/admin/pcscfg.cfg

\$ gcc -g -o main main.c -I/home/ora/ora9/oracle/precomp/public -L/home/ora/ora9/oracle/lib -lclntsh

\$ ./main

  ORA-12541: TNS:no listener

成功编译运行,这里也可以使用《ProC动态SQL示例(第1,2,3种方法)》一文中的示例,将//注释全部替换为空,即可编译。

http://blog.csdn.net/liwei_cmg/archive/2006/05/29/759963.aspx

不过会有告警提示:

/tmp/ccC7E6qe.o(.text+0xea): In function `db_connect':

/home/ora/develop/src/db.c:385: the `gets' function is dangerous and should not be used.

这个是由于使用了gets函数所致,见gets的man手册:

BUGS

Never use gets().  Because it is impossible to tell without knowing the data in advance how many  characters  gets()  will  read,  and  because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use.  It has  been  used  to  break  computer security.  Use fgets() instead.

It  is  not  advisable  to  mix calls to input functions from the stdio library with low - level calls to read() for the file descriptor  asso-ciated  with  the  input stream; the results will be undefined and very probably not what you want.

要解决这个问题,可以使用scanf函数替换gets,获取屏幕输入。如 scanf("%s",cmd)。

用 sqlplus 程序通过 test.testserver.com 网络服务名测试,如sqlplus system/manager@test.testserver.com。

关于为什们在网络服务名后面加 db_domain 参数,需要了解 sql*plus 连接数据库的原理,我在后面解决12154常见故障中给出了详细的说明。

如果上面的招数还不奏效的话,只好用一下乾坤大挪移了。

将客户端的网络服务名部分

test.testserver.com =

(DESCRIPTION=

(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))

)

(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)

)

)

拷贝到服务器的 tnsnames.ora 文件中。然后再服务器端用 sqlplus system/manager@test.testserver.com 连接到数据库。

如果能连接成功,说明你的客户端与服务器端的网络有问题。

如果连接不成功,用前面的部分检查网络服务名部分部分是否正确,如果确信网络服务名部分正确而且所有的客户端都连不上数据库则可能为系统 TCP/IP 或 Oracle 系统有问题,建议重新安装数据库。

常见故障解决办法:

TNS-12154 (ORA-12154):TNS:could not resolve service name

该错误表示用于连接的网络服务名在 tnsnames.ora 文件中不存在,如上面的 tnsnames.ora 中的网络服务名只有test,假如用户在连接时用 sqlplus system/manager@test1 则就会给出TNS-12154错误。

要注意的是,有时即使在 tnsnames.ora 文件中有相应的网络服务名,可是用该网络服务名连接时还会出错,出现这种情况的典型配置如下(在客户端的机器上):

sqlnet.ora 文件:

NAMES.DIRECTORY_PATH = (TNSNAMES, ….)

NAMES.DEFAULT_DOMAIN = server.com

tnsnames.ora 文件:

test =

(DESCRIPTION=

(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=testserver)(PORT=1521))

)

(CONNECT_DATA=(SERVICE_NAME=orcl.testserver.com)

)

)

sql*plus 运行基本机理:

在用户输入 sqlplus system/manager@test 后,sqlplus 程序会自动到 sqlnet.ora 文件中找 NAMES.DEFAULT_DOMAIN 参数,假如该参数存在,则将该参数中的值取出,加到网络服务名的后面,即此例中你的输入由 sqlplus system/manager@test 自动变为 sqlplus system/manager@test.server.com ,然后再到 tnsnames.ora 文件中找 test.server.com 网络服务名,这当然找不到了,因为该文件中只有 test 网络服务名,所以报错。解决的办法就是将 sqlnet.ora 文件中的 NAMES.DEFAULT_DOMAIN 参数注释掉即可,如 #NAMES.DEFAULT_DOMAIN = server.com。假如 NAMES.DEFAULT_DOMAIN 参数不存在,则 sqlplus 程序会直接到 tnsnames.ora 文件中找 test 网络服务名,然后取出其中的 host,port,tcp,service_name,利用这些信息将连接请求发送到正确的数据库服务器上。

另外原则上 tnsnames.ora 中的配置不区分大小写,但是我的确遇到区分大小写的情况,所以最好将使用的网络服务与 tnsnames.ora 中配置的完全一样。

ORA-12514: TNS:listener could not resolve SERVICE_NAME given in connect Descriptor.

该错误表示能在 tnsnames.ora 中找到网络服务名,但是在 tnsnames.ora 中指定的 SERVICE_NAME 与服务器端的 SERVICE_NAME 不一致。解决的办法是修改 tnsnames.ora 中的 SERVICE_NAME。

易混淆术语介绍:

Db_name:对一个数据库(Oracle database)的唯一标识,该数据库为第一章讲到的 Oracle database。这种表示对于单个数据库是足够的,但是随着由多个数据库构成的分布式数据库的普及,这种命令数据库的方法给数据库的管理造成一定的负担,因为各个数据库的名字可能一样,造成管理上的混乱。为了解决这种情况,引入了Db_domain参数,这样在数据库的标识是由 Db_name 和 Db_domain 两个参数共同决定的,避免了因为数据库重名而造成管理上的混乱。这类似于互连网上的机器名的管理。我们将 Db_name 和 Db_domain 两个参数用’.’连接起来,表示一个数据库,并将该数据库的名称称为 Global_name,即它扩展了 Db_name。Db_name 参数只能由字母、数字、’_’、’#’、’\$’组成,而且最多8个字符。

Db_domain:定义一个数据库所在的域,该域的命名同互联网的’域’没有任何关系,只是数据库管理员为了更好的管理分布式数据库而根据实际情况决定的。当然为了管理方便,可以将其等于互联网的域。

Global_name:对一个数据库(Oracle database)的唯一标识,Oracle建议用此种方法命名数据库。该值是在创建数据库时决定的,缺省值为 Db_name. Db_domain。在以后对参数文件中 Db_name 与 Db_domain 参数的任何修改不影响 Global_name 的值,如果要修改 Global_name,只能用 ALTER DATABASE RENAME GLOBAL_NAME TO 命令进行修改,然后修改相应参数。

Service_name:该参数是 Oracle8i 新引进的。在8i以前,我们用 SID 来表示标识数据库的一个实例,但是在 Oracle 的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了 Service_name 参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为 Db_name. Db_domain,即等于 Global_name。一个数据库可以对应多个 Service_name,以便实现更灵活的配置。该参数与 SID 没有直接关系,即不必 Service name 必须与 SID 一样。

Net service name:网络服务名,又可以称为数据库别名(database alias)。是客户端程序访问数据库时所需要,屏蔽了客户端如何连接到服务器端的细节,实现了数据库的位置透明的特性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值