• 14505阅读
  • 7回复

[提问]对字符集为US7ASCII的Oracle库,Qt如何提取显示中文字符? [复制链接]

上一主题 下一主题
离线adria
 

只看楼主 倒序阅读 楼主  发表于: 2010-12-01
— 本帖被 XChinux 从 Qt基础编程 移动到本区(2013-04-01) —
 用Qt连接一个oracle数据库,从中取的varchar2字符,用QString显示,中文都是乱码,英文和数字显示是正常的。该数据库字符集是US7ASCII(建立起来有些年头了)。

我从精华区XChinux网友的帖子中得到灵感,想到可否先转variant为QByteArray,这中间应该不损失数据,然后转QByteArray为GB2312。

QString ByteArray_to_GB(QByteArray strText)
{
    return QString::fromLatin1(strText.data());
}

QString code,inp,nameGB;
QByteArray name;

name = query.value(1).toByteArray();    //toString()?; 问题1
nameGB=ByteArray_to_GB(name);      //  问题2


ui.textBrowser->insertPlainText(code+"  "+nameGB+"  "+inp+"\n");

结果显示出来是乱码(是“?”号,或其他乱码,具体请见附件或下面我的回帖)。

现在想请教大家的是:1、将query.value(1)中取得的值(variant)转储为什么类型,还是不用转型。
                                        2、将这个值如何变换才能在QString中正常显示出来。
Qt和oracle字符集兼容.zip (53 K) 下载次数:27  (zip格式附件)

以下是选用不同Codec的结果:
main.cpp中,codec选用如下的三种,程序有三种不同结果:

一:GB18030GB2312




QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030"));
 
二、Utf8
QTextCodec::setCodecForLocale(QTextCodec::codecForName("Utf8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Utf8"));

三、ASCII
QTextCodec::setCodecForLocale(QTextCodec::codecForName("ASCII"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("ASCII"));






[ 此帖被adria在2010-12-01 23:39重新编辑 ]
离线lxbin2003

只看该作者 1楼 发表于: 2010-12-01
首先,你用sqlplus,保证你插入和查询出来的中文没有乱码,能够正常显示。
然后,再用QT连接,基本上不需要转换,就能直接显示。编码由oracle客户端去处理,你只管显示。
离线adria

只看该作者 2楼 发表于: 2010-12-01
谢谢你的回复。不过我用自己编译的OCI连接的oracle库,本机(客户机)不必有oracle客户端,直接能连上数据库服务端。
这样就有一个问题:我必须自己处理不同字符集显示问题。
之前我曾试用ODBC连oracle数据库,是用到oracle客户端的。当时字符显示上也没成功,不过一时想不起是否用过类型转换了。
还是想请教怎样转换query.value(1)(类型:variant)至QString,使QString能显示中文字符?不胜感谢
[ 此帖被adria在2010-12-01 23:32重新编辑 ]
离线lxbin2003

只看该作者 3楼 发表于: 2010-12-02
你自己编译的OCI库?你有oracle给你的数据库连接源码?
或者你编译的是QOCI?那oracle给你全部静态库了吗?否则,你还是离不开oracle客户端,你还是需要字符集同步。
query.value(1)转QString很简单,query.value(1).toString()即可.
离线adria

只看该作者 4楼 发表于: 2011-09-19
有关于这个问题:
数据库NLS为US7ASCII,客户端NLS相同,用SQLPLUS可以得到正确中文结果。
离线adria

只看该作者 5楼 发表于: 2011-09-19
确实如3楼所说,还是需要oracle_client做数据转换工作。不过
            QByteArray ba;
            QString name;
            ba = query.value(0).toByteArray();  
            name = query.value(0).toString();
            quint8 uin8_1,uin8_2;
            uin8_1=ba[0];
            uin8_2=ba[1];
        如果数据库NLS为US7ASCII,而字段中存的是“中”字,name的结果是两个乱码,这个uin8_1和uin8_2最后的结果是63(ASCII码的“?”),说明OCI已经将原始数据丢失了,而进行过转换了。
        从上面的试验看出,query.value(0)得到的数据就不是有意义的数据,而是ASCII码“?”。所以如何从US7ASCII数据库取出GB2312编码的字符,OCI还是没有做好的。或者说Oracle的OCI.dll似乎没有考虑这种问题,数据库中大于127的ASCII码值直接变成“?”了。
        只要能直接得到原始数据,再转换成双字节编码(当然要有一些变换),就可以得到GB2312了。不知道能否通过OCI直接得到字段原始数据
离线lkf_sk
只看该作者 6楼 发表于: 2011-11-01
狂顶你,我愁死了就是这个问题,得到的是63?,而且我将oracle数据库换成utf8编码的也不行,写进去一样,但是我写进去再读出来时能够还原的,比如我写“我”字进去,读出来还是“我”字,但是数据库里面显示的就是乱码了,哪位哥们知道咋回事,告诉我一下,小弟在这跪求了!!!
离线zhixiangxu

只看该作者 7楼 发表于: 2018-03-18
老哥,这么多年有解决没,,,我现在提取的没问题,但插入时又是乱码了。。。
快速回复
限100 字节
 
上一个 下一个