• 7718阅读
  • 11回复

[提问](已解决)Qt+mysql中文问题,有测试代码及结果,求解 [复制链接]

上一主题 下一主题
离线kummar
 
只看楼主 倒序阅读 楼主  发表于: 2011-07-07
— 本帖被 XChinux 从 Qt基础编程 移动到本区(2013-04-01) —
问题也描述不清楚,请看几行代码结其运行结果,代码很简单,红色部分是有区别的地方,请高人解答一下,谢谢。主要问题是想解决QT连接MYSQL后能使用中文
解决方法见7楼
测试1:
   QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("SchoolDB");
    db.setUserName("root");
    db.setPassword("123456");
    qDebug()<<"db open=" <<db.open();
    db.exec("SET NAMES 'utf8'");
    QSqlQuery query(db);
    qDebug()<<"drop="    <<query.exec("DROP TABLE student");   //删除现存的student表
    qDebug()<<"create="  <<query.exec("CREATE TABLE student(name varchar(20),id int)");  //建立表student
    qDebug()<<"insert="  <<query.exec("INSERT INTO student(name,id) VALUES('张三',34)");  //插入数据
    qDebug()<<"select="  <<query.exec("SELECT * FROM student");    //以下几行是显示表中所有数据
    while(query.next()){
        QString name = query.value(0).toString();
        int id=query.value(1).toInt();
       qDebug()<<"name="<<name<<",id="<<id;
    }
   db.close();
结果:
   db open= true
   drop= true
   create= true
   insert= false     //有最前面三行代码及插入语句中有中文就插入失败,可以比较测试1与测试2,也可对比测试1与测试3
   select= true
测试2:

   QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
    
   QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("SchoolDB");
    db.setUserName("root");
    db.setPassword("123456");
    qDebug()<<"db open=" <<db.open();
    db.exec("SET NAMES 'utf8'");
    QSqlQuery query(db);
    qDebug()<<"drop="    <<query.exec("DROP TABLE student");
    qDebug()<<"create="  <<query.exec("CREATE TABLE student(name varchar(20),id int)");
   qDebug()<<"insert="  <<query.exec("INSERT INTO student(name,id) VALUES('zhangshan',34)");
    qDebug()<<"select="  <<query.exec("SELECT * FROM student");
    while(query.next()){
        QString name = query.value(0).toString();
        int id=query.value(1).toInt();
       qDebug()<<"name="<<name<<",id="<<id;
    }
   db.close();
结果:   //对比测试1与测试2
  db open= true
   drop= true    
   create= true
   insert= true    
   select= true
   name= "zhangshan" ,id= 34
测试3:

   //QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
   // QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    //QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
  
   QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("SchoolDB");
    db.setUserName("root");
    db.setPassword("123456");
    qDebug()<<"db open=" <<db.open();
    db.exec("SET NAMES 'utf8'");
    QSqlQuery query(db);
    qDebug()<<"drop="    <<query.exec("DROP TABLE student");
    qDebug()<<"create="  <<query.exec("CREATE TABLE student(name varchar(20),id int)");
    qDebug()<<"insert="  <<query.exec("INSERT INTO student(name,id) VALUES('张三',34)");
    qDebug()<<"select="  <<query.exec("SELECT * FROM student");
    while(query.next()){
        QString name = query.value(0).toString();
        int id=query.value(1).toInt();
       qDebug()<<"name="<<name<<",id="<<id;
    }
   db.close();
结果:                       //对比测试1与测试3
  db open= true  
  drop= true  
create= true  
  insert= true  
  select= true   name= "??èy" ,id= 34   //中文乱码



离线XChinux

只看该作者 1楼 发表于: 2011-07-07
把有汉字的部分,用QString("张三")转成QString字符串再放上去。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线kummar
只看该作者 2楼 发表于: 2011-07-07
回 1楼(XChinux) 的帖子
谢谢版主解答,但按你的方法改了代码还是不行的
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));

    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("SchoolDB");
    db.setUserName("root");
    db.setPassword("123456");
    qDebug()<<"db open=" <<db.open();
    db.exec("SET NAMES 'utf8'");
    QSqlQuery query(db);
    qDebug()<<"drop="    <<query.exec("DROP TABLE student");
    qDebug()<<"create="  <<query.exec("CREATE TABLE student(name varchar(20),id int)");
    qDebug()<<"insert="  <<query.exec(QString("INSERT INTO student(name,id) VALUES('%1',34)").arg(QString("张三")));  
qDebug()<<"select="  <<query.exec("SELECT * FROM student");
    while(query.next()){
        QString name = query.value(0).toString();
        int id=query.value(1).toInt();
       qDebug()<<"name="<<name<<",id="<<id;
    }
   db.close();
运行结果:
db open= true
drop= true
create= true
insert= false
select= true
离线XChinux

只看该作者 3楼 发表于: 2011-07-07
我就是那样用的啊。

你数据库的charset是什么?那个数据表的charset 呢?
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 4楼 发表于: 2011-07-07
insert= false ,看看query.lastError()
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线kummar
只看该作者 5楼 发表于: 2011-07-07
把lastError打出来是这样的
lastError= "Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'name' at row 1 QMYSQL3: Unable to execute statement"

在命令行下查看charset是这样的
mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+----------------------------------------------------
-----+
| Variable_name            | Value
     |
+--------------------------+----------------------------------------------------
-----+
| character_set_client     | latin1
     |
| character_set_connection | latin1
     |
| character_set_database   | latin1
     |
| character_set_filesystem | binary
     |
| character_set_results    | latin1
     |
| character_set_server     | latin1
     |
| character_set_system     | utf8
     |
| character_sets_dir       | C:\Program Files\MySQL\MySQL Server 5.1\share\charsets\ |


但我用这几个命令在命令行下设置了也不行

set character_set_client =gb2312;
set character_set_connection =gb2312;
set   character_set_database =gb2312;
set character_set_results =gb2312;
set character_set_server =gb2312;

把命令行关了,再次打开查看charset还是跟上面一样的
离线XChinux

只看该作者 6楼 发表于: 2011-07-07
数据库、数据库表、数据库表字符串相关字段的charset设置为utf-8的。这你得去搜索关于mysql方面的文章了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线kummar
只看该作者 7楼 发表于: 2011-07-07
回 6楼(XChinux) 的帖子
恩,多谢版主耐心指导,问题基本解决,
个人认为解决中文问题关键所在是:QT与MYSQL设置的字符集要一致
做到这一点,我的工作有,在建起立数据库时指定默认字符集
在命令行下建立数据库
create database ShoolDB DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;
在QT程序的main.cpp中加入
QTextCodec::setCodecForLocale(QTextCodec::codecForName("gbk"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("gbk"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));

打开数据库后执行
db.exec("SET NAMES 'gbk'");
做了这几步应该就能保证QT与MYSQL设置的字符集要一致了。
现在的测试代码及结果
代码:
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
        QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
        QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
        db.setHostName("localhost");
        db.setDatabaseName("SchoolDB");
        db.setUserName("root");
        db.setPassword("123456");
        qDebug()<<"db open=" <<db.open();
        db.exec("SET NAMES 'gbk'");
        QSqlQuery query(db);
        qDebug()<<"drop="    <<query.exec("DROP TABLE student");   //删除现存的student表
        qDebug()<<"create="  <<query.exec("CREATE TABLE student(name varchar(20),id int)");  //建立表student
        qDebug()<<"insert="  <<query.exec(QString("INSERT INTO student(name,id) VALUES('%1',34)").arg(QString("张三")));  //插入数据
        qDebug()<<"select="  <<query.exec("SELECT * FROM student");    //以下几行是显示表中所有数据
        while(query.next()){
            QString name = query.value(0).toString();
            int id=query.value(1).toInt();
           qDebug()<<"name="<<name<<",id="<<id;
        }
       db.close();

结果:
db open= true
drop= true
create= true
insert= true
select= true
name= "张三" ,id= 34




离线liwshuo

只看该作者 8楼 发表于: 2011-07-10
非常感谢lz的帖子,但是测试了下,如果汉字是单数个,insert=false的。有什么解决方法没
离线kummar
只看该作者 9楼 发表于: 2011-07-11
回 8楼(liwshuo) 的帖子
这个真的是个问题啊,我也刚发现,还不知道怎么解决
离线liwshuo

只看该作者 10楼 发表于: 2011-07-11
    db.exec("SET NAMES 'gbk'");这个gbk改成gbk2312就ok了
离线XChinux

只看该作者 11楼 发表于: 2011-07-11
说到底还是Mysql的相关设置问题。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
快速回复
限100 字节
 
上一个 下一个