Sqlite SQLDescribeCol()返回二进制、BLOB、WCHAR、十进制的SQL_VARCHAR
使用UnderUnixODBC,我经常从SQLDescribeCol得到无用的结果 例如,在使用以下项创建的表中:Sqlite SQLDescribeCol()返回二进制、BLOB、WCHAR、十进制的SQL_VARCHAR,sqlite,odbc,unixodbc,Sqlite,Odbc,Unixodbc,使用UnderUnixODBC,我经常从SQLDescribeCol得到无用的结果 例如,在使用以下项创建的表中: CREATE TABLE `test_table` ( id INTEGER PRIMARY KEY NOT NULL, `value` BINARY(3) NOT NULL ) 我执行简单的无参数ODBC查询: SELECT value FROM `test_table` 这将返回一个包含一列的结果集,其中我的C代码表示以下内容: SQLWCHAR title
CREATE TABLE `test_table` (
id INTEGER PRIMARY KEY NOT NULL,
`value` BINARY(3) NOT NULL
)
我执行简单的无参数ODBC查询:
SELECT value FROM `test_table`
这将返回一个包含一列的结果集,其中我的C代码表示以下内容:
SQLWCHAR title[COLUMN_TITLE_SIZE];
SQLSMALLINT title_length;
SQLSMALLINT sql_type;
SQLULEN column_size;
SQLSMALLINT precision;
SQLSMALLINT nullable;
SQLRETURN rc = SQLDescribeColW(
hstmt,
column_index, // 1 in this case
&title[0],
COLUMN_TITLE_SIZE,
&title_length,
&sql_type,
&column_size,
&precision,
&nullable
);
尽管表定义中有二进制代码,但返回的却是sql\u type==sql\u VARCHAR
。对于某些类型,例如整数、时间/日期、SQL_位或大多数浮点数,不存在此问题。但BLOB列、NCHAR列,尤其是DECIMAL列也会发生同样的情况
我试图为语言绑定中从列返回的值自动选择正确的类型,因此区分这种类型很重要。这似乎是SQLite unixodbc驱动程序中的一个错误(或未实现的功能)。问题似乎在于,对于必须
malloc()
任意缓冲区的任何类型,其内部类型都是相同的
这里有一个建议的解决方法:驱动程序实际上知道列类型的字符串名称……您可以通过传递SQL\u DESC\u type\u name
来获取它
char type_name[100]; // Note: `typename` is a C++ keyword
SQLSMALLINT type_name_len;
rc = SQLColAttribute( // or SQLColAttributeW--see NOTE below
hstmt, // StatementHandle
column_index, // ColumnNumber
SQL_DESC_TYPE_NAME, // FieldIdentifier, see SQL_DESC_XXX list
&type_name, // CharacterAttributePtr
100, // BufferLength
&type_name_len, // StringLengthPtr
nullptr // NumericAttributePtr, not needed w/string attribute
);
注:上述操作在unixodbc上进行。但有报道称,尽管调用了SQLColAttribute
而不是SQLColAttributeW
,但Windows SQLite驱动程序返回了一个宽字符串作为类型名称。如果有人对此有更多的话要说,请插话。
这个type\u name
将返回并给您诸如BINARY之类的区别,因此如果您在其中查找所需类型的模式,您可以生成所需的SQL\u BINARY等类型
注意:驱动程序中有代码要执行。但是它似乎没有在选择中使用它,只在插入中使用。
SqlColAttribute
是一个简单的#定义到SqlColAttributeW
或SqlColAttributeA
,其中W函数用于“Unicode”字符集(使用wstring/SQLWCHAR),而a函数用于“多字节字符集”(使用strind/SQLCHAR)。如果定义了UNICODE
,通常会启用W函数。这与(几乎)的工作原理类似所有windows函数,请参阅以了解一般情况,或者odbc的情况如下:@erg Hmmm…哦。那么SQLCOLATTEREA保证在unix odbc上定义吗?我实际上是在Linux上编译的,而不是在windows上编译的,但对windows用户来说有所不同…这表明可能定义了UNICODE,因此称为“SQLCOLATTERE”我想我得到的是W版本…我(大部分)在windows上,不会直接针对任何“A”或“W”版本编写代码,这感觉是错误的。因此,我也不会依赖UnixOdbc定义任何“A”变体。您可能可以依赖windows上的A函数,并执行一些丑陋的操作,如\ifdef WIN32..\endif
。不久前,我编写了一个跨平台的odbc wr我们的一个项目的apper,我刚刚使用了std::string(utf-8编码)无论是在任何地方,还是在任何涉及到windows API边界的地方,我都会从utf-8转换为使用unicode的wstring:@erg感谢您的洞察力……我想我现在只会坚持使用W版本,因为到目前为止,在测试中,这似乎是最有效的(例如,没有混淆,W API始终是宽字符)。