[Snowflake-ODBC]使用SQLColumns API无法成功获取列信息

问题描述

我遇到了SNow-odbc驱动程序问题,以收集表中所有列的元数据;

A>从以下位置下载odbc驱动程序 https://sfc-repo.snowflakecomputing.com/odbc/linux/2.21.6/snowflake_linux_x8664_odbc-2.21.6.tgz

B>在雪花站点中使用doc安装和配置odbc驱动程序: https://docs.snowflake.com/en/user-guide/odbc-linux.html

自动使用unixodbc_setup.sh安装它,并且仅更新SF_ACCOUNT信息,在/etc/odbc.ini中配置数据库和仓库值

c>使用运行良好的isql测试驱动程序

[root@sflake1 lib]# isql -v sNowflake user password

+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
sql> select * from test_vch
+-----------+-----+--------------------------------------------------+
| V10       | V100                                                                                                | V255                                                                                                                                                                                                                                                           |
+-----------+------------------+----------------+
| v10       | v100                                                                                                | v255                                                                                                                                                                                                                                                           |
| a         | b                                                                                                   | c                                                                                                                                                                                                                                                              |
| aa        | bb                                                                                                  | cc                                                                                                                                                                                                                                                             |
+-----------+---------------+
sqlRowCount returns 3
3 rows fetched
sql> quit;

d>我尝试使用sqlCOLUMNS API获取列; 像下面那样实现经过测试的C代码

RETCODE getColumns(sqlHSTMT hstmt,sqlCHAR* tablename)
{

    sqlRETURN rc;

    sqlCHAR szSchema[STR_LEN];
    sqlCHAR szCatalog[STR_LEN];
    sqlCHAR szColumnName[STR_LEN];
    sqlCHAR szTableName[STR_LEN];
    sqlCHAR szTypeName[STR_LEN];
    sqlCHAR szRemarks[REM_LEN];
    sqlCHAR szColumnDefault[STR_LEN];
    sqlCHAR szIsNullable[STR_LEN];

    sqlINTEGER ColumnSize;
    sqlINTEGER BufferLength;
    sqlINTEGER CharOctetLength;
    sqlINTEGER OrdinalPosition;

    sqlSMALLINT DataType;
    sqlSMALLINT DecimalDigits;
    sqlSMALLINT NumPrecRadix;
    sqlSMALLINT Nullable;
    sqlSMALLINT sqlDataType;
    sqlSMALLINT DatetimeSubtypeCode;

    sqlLEN cbCatalog;
    sqlLEN cbSchema;
    sqlLEN cbTableName;
    sqlLEN cbColumnName;
    sqlLEN cbDataType;
    sqlLEN cbTypeName;
    sqlLEN cbColumnSize;
    sqlLEN cbBufferLength;
    sqlLEN cbDecimalDigits;
    sqlLEN cbNumPrecRadix;
    sqlLEN cbNullable;
    sqlLEN cbRemarks;
    sqlLEN cbColumnDefault;
    sqlLEN cbsqlDataType;
    sqlLEN cbDatetimeSubtypeCode;
    sqlLEN cbCharOctetLength;
    sqlLEN cbOrdinalPosition;
    sqlLEN cbIsNullable;

    sqlLEN numRecs = 0;
    sqlCHAR       sqlState[6],sqlStmt[100],Msg[sql_MAX_MESSAGE_LENGTH];
    sqlINTEGER    NativeError;
    sqlSMALLINT   i,MsgLen;

    rc = sqlColumns(hstmt,NULL,(sqlCHAR*)"PUBLIC",sql_NTS,tablename,0);
    if (rc == sql_SUCCESS || rc == sql_SUCCESS_WITH_INFO) {

      sqlBindCol(hstmt,1,sql_C_CHAR,szCatalog,STR_LEN,&cbCatalog);
      sqlBindCol(hstmt,2,szSchema,&cbSchema);
      sqlBindCol(hstmt,3,szTableName,&cbTableName);
      sqlBindCol(hstmt,4,szColumnName,&cbColumnName);
      sqlBindCol(hstmt,5,sql_C_SSHORT,&DataType,&cbDataType);
      sqlBindCol(hstmt,6,szTypeName,&cbTypeName);
      sqlBindCol(hstmt,7,sql_C_SLONG,&ColumnSize,&cbColumnSize);
      sqlBindCol(hstmt,8,&BufferLength,&cbBufferLength);
      sqlBindCol(hstmt,9,&DecimalDigits,&cbDecimalDigits);
      sqlBindCol(hstmt,10,&NumPrecRadix,&cbNumPrecRadix);
      sqlBindCol(hstmt,11,&Nullable,&cbNullable);
      sqlBindCol(hstmt,12,szRemarks,REM_LEN,&cbRemarks);
      sqlBindCol(hstmt,13,szColumnDefault,&cbColumnDefault);
      sqlBindCol(hstmt,14,&sqlDataType,&cbsqlDataType);
      sqlBindCol(hstmt,15,&DatetimeSubtypeCode,&cbDatetimeSubtypeCode);
      sqlBindCol(hstmt,16,&CharOctetLength,&cbCharOctetLength);
      sqlBindCol(hstmt,17,&OrdinalPosition,&cbOrdinalPosition);
      sqlBindCol(hstmt,18,szIsNullable,&cbIsNullable);
    }

    while (sql_SUCCESS == rc) {
       rc = sqlFetch(hstmt);
       if (rc == sql_NO_DATA_FOUND){
          printf("sql_NO_DATA_FOUND:All result done...");
          break;
       }
       else if(rc != sql_SUCCESS){
         sqlGetDiagField(sql_HANDLE_STMT,hstmt,sql_DIAG_NUMBER,&numRecs,0);
         // Get the status records.
         i = 1;
         while (i <= numRecs && (rc = sqlGetDiagRec(sql_HANDLE_STMT,i,sqlState,&NativeError,Msg,sizeof(Msg),&MsgLen)) != sql_NO_DATA) {
            printf("sqlState:%s\n",sqlState);               <------ Will show errors here
            printf("NativeError:%d\n",NativeError);
            printf("Msg:%s\n",Msg);
            i++;
         }
         break;
       }

       printf("szColumnName=%s,szTypeName=%s,DataType=%d,ColumnSize=precision=%d",DataType,ColumnSize);
    }

        sqlFreeStmt(hstmt,sql_UNBIND);
        sqlFreeStmt(hstmt,sql_CLOSE);

        return rc;
}

错误消息显示

sqlState:S1000
NativeError:6
Msg:[SNowflake][SNowflake] (6) 
 

 Assertion failure: USER_DEFINED_TYPE_type_unsupported

odbc.ini,odbcinst.ini和simba.sNowflake.ini如下:

[root@sflake1 log]# more /etc/odbc.ini 

[sNowflake]
Description=SNowflakeDB
Driver=SNowflakeDSIIDriver
Locale=en-US
SERVER=cy72957.us-east-2.aws.sNowflakecomputing.com
PORT=443
SSL=on
ACCOUNT=cy72957.us-east-2.aws
database=testdbu
Warehouse=COmpuTE_WH
[root@sflake1 log]# more /etc/odbcinst.ini 
# Example driver deFinitions

# Driver from the postgresql-odbc package
# Setup from the unixODBC package
[Postgresql]
Description = ODBC for Postgresql
Driver      = /usr/lib/psqlodbcw.so
Setup       = /usr/lib/libodbcpsqlS.so
Driver64    = /usr/lib64/psqlodbcw.so
Setup64     = /usr/lib64/libodbcpsqlS.so
FileUsage   = 1


# Driver from the mysql-connector-odbc package
# Setup from the unixODBC package
[MysqL]
Description = ODBC for MysqL
Driver      = /usr/lib/libmyodbc5.so
Setup       = /usr/lib/libodbcmyS.so
Driver64    = /usr/lib64/libmyodbc5.so
Setup64     = /usr/lib64/libodbcmyS.so
FileUsage   = 1

[SNowflakeDSIIDriver]
APILevel=1
ConnectFunctions=YYY
Description=SNowflake DSII
Driver=/root/sNowflake/sNowflake_odbc/lib/libSNowflake.so
DriverODBCVer=03.52
sqlLevel=1
[root@sflake1 lib]# more simba.sNowflake.ini
# To use this INI file,replace [INSTALLDIR] with the 
# directory the tarball was extracted to.

[Driver]
ANSIENCODING=UTF-8

## Note that this default DriverManagerEncoding of UTF-32 is for iODBC. unixODBC uses UTF-16 by default.
## If unixODBC was compiled with -Dsql_WCHART_CONVERT,then UTF-32 is the correct value.
## Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC
DriverManagerEncoding=UTF-16
DriverLocale=en-US
ErrorMessagesPath=/root/sNowflake/sNowflake_odbc/ErrorMessages/
LogLevel=0
LogNamespace=
LogPath=/root/sNowflake/sNowflake_odbc/log
CURLVerboseMode=false
CABundleFile=/path/to/cacert.pem

## - Uncomment the ODBCInstLib corresponding to the Driver Manager being used.
## - Note that the path to your ODBC Driver Manager must be specified in LD_LIBRARY_PATH (LIBPATH for AIX,DYLD_LIBRARY_PATH for Darwin).
## - Note that AIX has a different format for specifying its shared libraries.

# Generic ODBCInstLib
#   iODBC
#ODBCInstLib=libiodbcinst.so.2

#   SimbaDM / unixODBC
#ODBCInstLib=libodbcinst.so

# Darwin specific ODBCInstLib
#   iODBC
#ODBCInstLib=libiodbcinst.dylib

# AIX specific ODBCInstLib
#   iODBC
#ODBCInstLib=libiodbcinst.a(libiodbcinst.so.2)

#   SimbaDM
#ODBCInstLib=libodbcinst.a(odbcinst.so)

#   unixODBC
ODBCInstLib=/usr/lib64/libodbcinst.so
CABundleFile=/root/sNowflake/sNowflake_odbc/lib/cacert.pem

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)