我们公司有一个CRM系统,它使用Oracle 11g数据库。它由第三方供应商开发。
我们无法访问运行CRM系统的服务器。但是,尽管如此,我们(SYS 用户)可以使用有效的 DBA 登录数据。它包括:
- 服务器 IP:172.1.2.3
- 端口:1521
- SID:ABC
- 用户: 系统
- 密码: *
我们可以使用它来访问带有Oracle SQL Developer 3.1(连接>>属性)的数据库
现在,必须将部分数据从 CRM 数据库复制到驻留在另一台服务器上的另一个 Oracle 数据库中。
据我了解,我需要在目标数据库中创建一个数据库链接。我尝试了这样的事情:
CREATE PUBLIC DATABASE LINK xxx CONNECT TO sys IDENTIFIED BY ***** USING 'MYTNSENTRY'
我的tnsnames.ora如下:
MYTNSENTRY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.1.2.3)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = abc)
)
)
....我的听众.ora看起来像这样:
MYLISTENER=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=172.1.2.3)(PORT=1521))
))
SID_LIST_MYLISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=MYTNSENTRY)
(ORACLE_HOME=C:somepath) # path to Oracle home of target DB
(PROGRAM=extproc)))
PROGRAM=extproc是正确的选择吗?还有其他几个程序可供选择。我什至无法使用 lsnrctl 启动侦听器,因为它无法"验证用户"或其他东西。具有讽刺意味的是,侦听器设置和指向MS SQL服务器的数据库链接工作顺利。
现在,尽管缺少有关CRM数据库系统的一些重要信息,但仍然可以在SQL Developer中连接到数据库。难道不应该在两个 Oracle 数据库之间建立连接吗?请帮助我设置和创建数据库链接。
-----编辑:--------
亚历克斯·普尔(Alex Poole)的提示帮助我让它工作。我用了
show parameters service_names;
以获取完整的服务名称。它的形式为 abc.def,def 是域。因此,我将域名添加到 tnsnames.ora 中的 TNS 别名中:
MYTNSENTRY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.1.2.3)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = abc.def)
)
)
可以在目标数据库服务器的命令提示符下使用 tnsping MYTNSENTRY 测试连接。tnsnames.ora 是本地的。但是,我删除了对"本地"侦听器.ora的所有更改,因为侦听器确实驻留在CRM服务器上。
SQL 命令基本保持不变,但现在连接有效:
CREATE PUBLIC DATABASE LINK xxx CONNECT TO some_user IDENTIFIED BY ***** USING 'MYTNSENTRY'
您说过SID
是abc
,但是在您的tnsnames.ora
中,您在CONNECT_DATA
部分中得到了SERVICE_NAME
。它们并不总是一回事 - 请参阅此问题或"询问汤姆"条目。您实际上还没有说出您遇到了什么错误,但只是将其更改为SID =
可能会有所作为。
listener.ora
,实际上是侦听器,位于托管CRM数据库的服务器上,而不是托管"目标"数据库的服务器上。因为您可以从显然已经配置好的SQL开发人员进行连接。tnsnames.ora
确实需要是本地的。
但是,如果您确实知道CRM数据库的service_name
,则可以跳过该数据库并使用EZCONNECT语法定义链接中的所有内容:
CREATE PUBLIC DATABASE LINK xxx
CONNECT TO non-sys IDENTIFIED BY *****
USING '//172.1.2.3:1521/service_name';
检查 SQL 开发人员配置,查看该配置是否已使用服务名称而不是 SID,如果没有,则需要发现它。如果您有权访问CRM服务器,则可以使用lsnrctl
来查找已注册的服务名称,但是由于您似乎不需要,因此您需要连接到数据库并运行show parameters service_names
或select value from v$parameter where name = 'service_names';
。
比创建私有链接需要更多的权限,并且公共链接可能不太安全,因为它将您的 CRM 数据库暴露给目标数据库上的任何人。因此,我只会在真正需要时才将其公开,并且如果您能够创建一个只读帐户,则无论哪种方式都连接到只读帐户。
另请注意,如果目标数据库global_names
设置为true
则数据库链接名称必须与远程服务名称匹配。
除非必要,否则您不仅不应以 SYS 身份连接,而且不能通过数据库链接以 SYS 身份连接。