【发布时间】:2019-12-08 17:52:17
【问题描述】:
我正在尝试使用 unixODBC 2.3.7 连接到 Oracle 19 数据库。 我正在使用 Oracle Developer Days VirtualBox VM。
当尝试通过isql 进行故障排除时,我总是收到此错误:
# isql -v -3 oracledsn
[HY000][unixODBC][Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
[ISQL]ERROR: Could not SQLConnect
遗憾的是我现在无法重现它,但上次尝试时我总是有
[IM004][unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV failed
[ISQL]ERROR: Could not SQLConnect
这是我从(专有)C++ 代码中得到的相同错误消息,所以我很确定问题只是连接设置。
我检查了https://www.connectionstrings.com/oracle/,但没有一个组合有效。
这是我所有的配置设置:
# odbcinst -j -130-
unixODBC 2.3.7
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /home/florian/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
# cat /usr/local/etc/odbcinst.ini
[oraclex]
Description = Oracle ODBC driver for Oracle 19
Driver = /mnt/libsqora.so.19.1
Setup =
FileUsage =
CPTimeout =
CPReuse =
Driver Logging = 7
[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log
ForceTrace = Yes
Pooling = No
DEBUG = 1
# cat ~/.odbc.ini
[oracledsn]
Driver = oraclex
Server = 10.1.6.19
Port = 1521
Uid = system
Pwd = oracle
Database = orclcdb/orcl/"<empty>"
ORA-12545: 连接失败,因为目标主机或对象不存在
我也试过ServerName
ServerName = //10.1.6.19/orclcdb or //10.1.6.19/orcl
[28000][unixODBC][Oracle][ODBC][Ora]ORA-01017: invalid username/password; logon denied
这是/tmp/odbc.log:
[ODBC][18832][1564563250.044774][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x1fd7780
[ODBC][18832][1564563250.044854][SQLSetEnvAttr.c][189]
Entry:
Environment = 0x1fd7780
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 0
[ODBC][18832][1564563250.044886][SQLSetEnvAttr.c][381]
Exit:[SQL_SUCCESS]
[ODBC][18832][1564563250.044914][SQLAllocHandle.c][377]
Entry:
Handle Type = 2
Input Handle = 0x1fd7780
[ODBC][18832][1564563250.044944][SQLAllocHandle.c][493]
Exit:[SQL_SUCCESS]
Output Handle = 0x1fd8090
[ODBC][18832][1564563250.044983][SQLConnect.c][3721]
Entry:
Connection = 0x1fd8090
Server Name = [oracledsn][length = 9 (SQL_NTS)]
User Name = [NULL]
Authentication = [NULL]
UNICODE Using encoding ASCII 'ANSI_X3.4-1968' and UNICODE 'UCS-2LE'
DIAG [HY000] [Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
[ODBC][18832][1564563250.082037][SQLConnect.c][4244]
Exit:[SQL_ERROR]
[ODBC][18832][1564563250.082070][SQLGetDiagRec.c][677]
Entry:
Connection = 0x1fd8090
Rec Number = 1
SQLState = 0x7fffeabcac60
Native = 0x7fffeabcac5c
Message Text = 0x7fffeabcac70
Buffer Length = 500
Text Len Ptr = 0x7fffeabcac5a
[ODBC][18832][1564563250.082092][SQLGetDiagRec.c][726]
Exit:[SQL_SUCCESS]
SQLState = HY000
Native = 0x7fffeabcac5c -> 12545
Message Text = [[unixODBC][Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
我也一直在尝试来自 https://www.easysoft.com/developer/languages/c/odbc_tutorial.html#connect_full 的 C 代码——结果基本相同。
# cat test2.c
# compile with gcc -I ../include test2.c -o test2 -lodbc
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
/*
* see Retrieving ODBC Diagnostics
* for a definition of extract_error().
*/
static void extract_error(
char *fn,
SQLHANDLE handle,
SQLSMALLINT type);
main() {
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN ret; /* ODBC API return status */
SQLCHAR outstr[1024];
SQLSMALLINT outstrlen;
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
/* Connect to the DSN mydsn */
ret = SQLDriverConnect(dbc, NULL, "DSN=oracledsn;", SQL_NTS,
outstr, sizeof(outstr), &outstrlen,
SQL_DRIVER_COMPLETE);
if (SQL_SUCCEEDED(ret)) {
printf("Connected\n");
printf("Returned connection string was:\n\t%s\n", outstr);
if (ret == SQL_SUCCESS_WITH_INFO) {
printf("Driver reported the following diagnostics\n");
//extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
SQLDisconnect(dbc); /* disconnect from driver */
} else {
fprintf(stderr, "Failed to connect\n");
//extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
/* free up allocated handles */
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
作为另一个参考点,我可以使用 sqlplus 从另一台机器连接到上述 Oracle Dev VM,如下所示:
./sqlplus sys/oracle@10.1.6.19/orclcdb as sysdba
SQL>
./sqlplus system/oracle@10.1.6.19/orclcdb
SQL>
在 VM 上,我有一个文件 /u01/app/oracle/product/version/db_1/network/admin/tnsnames.ora,但我不确定客户端上是否也需要一个文件?
ORCLCDB=localhost:1521/orclcdb
ORCL=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
【问题讨论】:
-
你必须有oracle.com/database/technologies/instant-client/downloads.html 并且应该正确设置一些系统变量 PS: srr my chinese
-
是的,我正在使用即时客户端,并且我还尝试了像
ORACLE_SID和TWO_TASK这样的环境变量,就像这里其他类似问题中所建议的那样,但我没有得到更好的结果。 -
设置 ORACLE_HOME、TNS_ADMIN 并将带有 dll 的文件夹添加到 PATH,然后尝试通过 sqlplus 从远程客户端连接。如果工作去调整 odbc ...
-
more explain ORACLE_HOME=
, TNS_ADMIN= / tnsnames shld content record as on u server.将 HOST 从 0.0.0.0 更改为有效 IP 服务器的地址 -
我终于找到了解决方案,尽管这是针对 12.2.0.1 而不是 19 ``` # cat .odbc.ini [oracledsn] Driver=oracle UID=system PWD=oracle DBQ=192.168.178.32 :1521/ORCLCDB ServerName=//192.168.178.32:1521/ORCLCDB ``` ``` cat /usr/local/etc/odbcinst.ini [oracle] 描述 = foo 驱动程序 = /mnt/libsqora.so.19.1 驱动程序日志= 7 UsageCount=1 FileUsage=1 [ODBC] Trace = Yes TraceFile = /tmp/odbc.log ForceTrace = Yes Pooling = No ```