• 10915阅读
  • 7回复

【提问】qt4.0 odbc sql driver bug [复制链接]

上一主题 下一主题
离线yfy002
 

只看楼主 倒序阅读 楼主  发表于: 2005-07-25
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
最近在使用qt4的odbc驱动取读image型数据时,发觉我上传的600多k字节的图像,取出来的只有130k,查找了下原因,问题出在qt4提供的odbc数据库驱动上。
在opensource 版的src\sql\drivers\odbc\qsql_odbc.cpp
文件里,读取image类型数据的函数是
static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
。。。。。。
它每次读取64k的字节,我的那个130k是它连续两次读取的数据。也就是说第二次后就退出了。
造成这个的原因我也不太清楚,不过我把它的代码如下部分修改后,可以读取全部类容了
if (lengthIndicator == SQL_NO_TOTAL) {
      read += colSize;
      colSize = 65536;
    } else {
      // read += lengthIndicator;//屏蔽修改为下面的
      read += colSize;
    }    
由于英文不是很好,麻烦版主向奇趣公司提交一下这个问题。
[ 此贴被XChinux在2005-08-02 09:12重新编辑 ]
我渴望平静,风却给了我涟漪
我的blog:
http://sungaoyong.cublog.cn
离线XChinux

只看该作者 1楼 发表于: 2005-07-25
已经向TrollTech提交了
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 2楼 发表于: 2005-07-26
下面是我向TrollTech提交你上面所说的问题后,TrollTech的回复:

Hi,
On Monday, 25. Jul 2005 10:44 hakusan@sohu.com wrote:
>> the question came from open source edition of
>> src\sql\drivers\odbc\qsql_odbc.cpp
>> file.
>> the function is :
>> static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
>> it read 64k bytes data,but it's only read twice, then exited.
>>
>> but while I modified the source file of follow:
>> if (lengthIndicator == SQL_NO_TOTAL) {
>>     read += colSize;
>>     colSize = 65536;
>>   } else {
>>     // read += lengthIndicator;//commented this line and replaced by
>>     the next line
>>     read += colSize;
>>   }
Indeed, the lengthIndicator variable will contain the number of bytes
still available to be read rather than the number of bytes that were
read. We'll see if this can be fixed for the next patch release.
Thanks for reporting.
--
Jan Erik Hanssen
Trolltech AS, Waldemar Thranes gate 98, NO-0175 Oslo, Norway
=======================================================================
Cast Your Vote!
Help shape the 2005 Trolltech Developer Days by voting for the topics
most important to you - and enter to win free admission to the Developer
Days or a 128Mb Trolltech USB pen. Complete the survey at
www.trolltech.com/campaign/devday.html.
=======================================================================
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 3楼 发表于: 2005-07-26
我的英文也很差劲,呵呵。幸亏对方看懂了。

TrollTech给出的回复是:

Indeed, the lengthIndicator variable will contain the number of bytes
still available to be read rather than the number of bytes that were
read. We'll see if this can be fixed for the next patch release.


翻译:事实上,变量lengthIndicator应该存储的是剩余字节数,而不是已经读取的字节数,我们看看是否能在下补丁中把Fixed了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线yfy002

只看该作者 4楼 发表于: 2005-08-17
根据TrollTech的回复,修改函数如下:
static QVariant qGetBinaryData(SQLHANDLE hStmt, int column)
{
  QByteArray fieldVal;
  SQLSMALLINT colNameLen;
  SQLSMALLINT colType;
  QSQLULEN colSize;
  SQLSMALLINT colScale;
  SQLSMALLINT nullable;
  QSQLLEN lengthIndicator = 0;
  SQLRETURN r = SQL_ERROR;

  SQLTCHAR colName[COLNAMESIZE];
  r = SQLDescribeCol(hStmt,
              column + 1,
              colName,
              COLNAMESIZE,
              &colNameLen,
              &colType,
              &colSize,
              &colScale,
              &nullable);
  if (r != SQL_SUCCESS)
    qWarning("qGetBinaryData: Unable to describe column %d", column);
  // SQLDescribeCol may return 0 if size cannot be determined
  if (!colSize)
    colSize = 255;
  else if (colSize > 65536) // read the field in 64 KB chunks
    colSize = 65536;

  fieldVal.resize(colSize);
  ulong read = 0;
  while (true) {
    r = SQLGetData(hStmt,
                column+1,
                SQL_C_BINARY,
                (SQLPOINTER)(fieldVal.constData() + read),//此处的"-read"改为"+read"
                fieldVal.size() - read,
                &lengthIndicator);
    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO)
        break;
    if (lengthIndicator == SQL_NULL_DATA)
        return QVariant(QVariant::ByteArray);
//if (lengthIndicator == SQL_NO_TOTAL) {
//修改为下面的内容,剩余字节>65536时继续读取,否则读取剩余的字节
if (lengthIndicator >65536) {
    read += colSize;
        colSize = 65536;
    } else {
        read += lengthIndicator;
        //read += colSize;
    }
    if (r == SQL_SUCCESS) { // the whole field was read in one chunk
        fieldVal.resize(read);
        break;
    }
    fieldVal.resize(fieldVal.size() + colSize);
  }
  return fieldVal;
}

在opensource版和商业版中运行通过
我渴望平静,风却给了我涟漪
我的blog:
http://sungaoyong.cublog.cn
离线XChinux

只看该作者 5楼 发表于: 2005-08-17
加精华应该,这是实际问题
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线hetal

只看该作者 6楼 发表于: 2006-01-10
能提交一个连接ODBC的例子吗?最近我用ODBC连接时,open打开了,就是出现“Driver not loaded”错误,我的驱动是有的麻烦了
离线hetal

只看该作者 7楼 发表于: 2006-01-10
问题已经解决,谢谢
快速回复
限100 字节
 
上一个 下一个