• 9991阅读
  • 8回复

DSN-LESS方式如何让FreeTDS使用cp850或utf-8连接数据库? [复制链接]

上一主题 下一主题
离线csoapy
 

只看楼主 正序阅读 楼主  发表于: 2009-01-06
— 本帖被 XChinux 执行加亮操作(2009-01-06) —
我在linux下用unixODBC + FreeTDS 0.82 + QT 4.4.3连接sql server 2000数据库。

之前因为在配置odbcinst.ini时按网上绝大多数教程说的把Setup一行设为unixodbc的libtds.so,结果连也连不上,字符集问题。后来再回头看freetds的手册时才发现,setup可以设为driver一样的。而且这样在用ODBCConfig配置数据源时给出的选项更多。

现在连数据库的时候能连上,也能取回列名(字母),但取不回数据。QTCreator的debug输出为:
app-stderr:qGetStringData: Error while fetching data (-1)。


并按手册建议指定db.setConnectOptions("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3");也没用。好像是因为虽然unixodbc支持odbc 3.5版(加入unicode支持),但freetds只支持到odbc 3.0。

以上这些问题最根本的地方其实是在sql.log这个日志里:
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
DIAG [HY003] [FreeTDS][SQL Server]Program type out of range
DIAG [42000] [FreeTDS][SQL Server]Some character(s) could not be converted into client's character set.  Unconverted bytes were changed to question marks ('?')

简体中文sql server 2000用的字符集好像是cp850,而FreeTDS用的是UCS,QT默认用latin-1,
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
也不行。
这到底如何是好?之间有些字符是无法转换的,所以出错。DSN-LESS方式就只有用FreeTDS库来生成SQL环境,SQL连接,然后再传给QODBCDriver( ),再传给QSqlDatabase::addDatabase( )?



离线neu_sunlei

只看该作者 8楼 发表于: 2010-03-31
我也遇到这个问题拉,那是不是说QT 在linux下就没有办法访问SQL SERVER 拉?
人之初,性本善。性相近,习相远。苟不教,性乃迁。教之道,贵以专。
离线daphne310
只看该作者 7楼 发表于: 2009-06-17
敢问后排男生大侠,上面所说的bug具体怎么改啊?
还望指教!
我现在用unixODBC+FreeTDS+QT远程访问MSSQL2000数据库,数据库可以连通,就是接进来的表名看不到,应该修改哪一段代码啊?
我自己改了一下Q_ODBC_VERSION_2,可以看到表名,但是是乱码,急啊!是不是改的不对?
请赐教!
离线ylnlp
只看该作者 6楼 发表于: 2009-03-14
REDHET LINUX 9 + C +SQL2000 这个东西应该怎么实现?
离线ylnlp
只看该作者 5楼 发表于: 2009-03-14
呵呵,我正在试用FREETDS,还没有成功,希望给予帮助,QQ305056289,谢谢
离线csoapy

只看该作者 4楼 发表于: 2009-01-10
切!自言自语!
离线csoapy

只看该作者 3楼 发表于: 2009-01-09
另外关于这个bug,qt官方网站的回复:

Answer from Trolltech: Connecting to a MySQL database using unixODBC works fine and hints that this may be caused by a problem in the FreeTDS driver.
Since FreeTDS doesn't support SQL_C_WCHAR the driver plugin has to be compiled with Q_ODBC_VERSION_2 defined, and since scrollable cursors arn't supported all queries must be executed in forwardOnly mode.

===============================

详见:
http://trolltech.com/developer/task-tracker/index_html?method=entry&id=154373

http://trolltech.com/developer/task-tracker/index_html?method=entry&id=230230
离线csoapy

只看该作者 2楼 发表于: 2009-01-09
终于找到原因了,是FreeTDS的一个BUG,在0.82里面没有修正的:

这是它新版本里部分文件的内容
odbc
- cursors (mssql)
- fixed database setting
- return error always if odbc returns SQL_ERROR
- fixed SQLGetData result


Tue Nov 04 16:24:24 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
    * src/odbc/odbc.c src/odbc/unittests/cursor3.c:
    - fix SQLGetData with cursors

就是那个SQLGetData了,看看qsql_odbc.cpp里面的代码
if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {...........
} else if (r == SQL_NO_DATA) {
    break;
} else {
    qWarning("qGetStringData: Error while fetching data (%d)", r);
    fieldVal = QString();
    break;
}

真是折腾人!浪费了我一个多星期的时间!
离线csoapy

只看该作者 1楼 发表于: 2009-01-06
我用tsql能连上,也能取回并正确显示字段,但用isql和DataManager(II)都不行。所以就看了下tsql的源码,相关的部分在这里:
static void populate_login(TDSLOGIN * login, int argc, char **argv)
它先取本机locole对应的字符集(我的机器上是en_US.UTF-8),然后再调用tds_set_client_charset(login, charset);
所以它能够连得上。

那么这是不是QODBCDriver和一个bug?因为我用UTF-8设置了setCodecForTr( )、setCodecForLocale( )、setCodecForCString( )都不行。sql.log里面还是显示:UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

所以我就想QODBCDriver的ctor有两个函数,sql环境和sql连接的句柄。我想通过odbc api从这两个参数入手,把字符集设定好再传给它。可是MSDN里的SQLSetConnectAttr( )和SQLSetConnectAttr( )函数里面都没找到相关的项。

或者再从freetds api入手?正在试……
快速回复
限100 字节
 
上一个 下一个