【问题标题】:Cannot connect to Oracle 19 with unixODBC无法使用 unixODBC 连接到 Oracle 19
【发布时间】: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_SIDTWO_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 ```

标签: oracle unixodbc


【解决方案1】:

我终于找到了解决方案,虽然这是针对 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]
Description = foo
Driver = /mnt/libsqora.so.19.1
Driver Logging = 7
UsageCount=1
FileUsage=1

[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log
ForceTrace = Yes
Pooling = No
# LD_LIBRARY_PATH=. isql -v oracledsn system oracle
+---------------------------------------+
| Connected!                            |

没有设置特定于 Oracle 的环境变量,但如果我将 ServerName 的值逐字替换为 TWO_TASK,它是否有效。

【讨论】:

    猜你喜欢
    • 2018-11-23
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2011-09-05
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多