qt 数据库增加字段且版本兼容

86 篇文章 1 订阅

数据库使用过程中经常会出现需要增加新的字段,这个时候又要兼容旧的版本。
我们增加字段往往用到“ALTER TABLE tablename ADD COLUMN 字段名 类型”的sql语句,而在qt中增加字段除了这个语句还需要几个类的配合,QSqlDatabase、QSqlError、QSqlQuery、QSqlRecord、QSqlField。
QSqlDatabase用来连接数据库,获取表数和表名;
QSqlError用来sql的执行错误;
QSqlQuery用来执行语句和获取执行后的结果;
QSqlRecord获取表的字段名;
QSqlField获取表的字段类型。

如果不想用Qt封装的接口查询数据库中的字段名和字段类型,可以使用“SELECT * FROM pragma_table_info(‘tablename’)”的方法来查询字段名和类型。

实例如下:

#ifndef WIDGET_H
#define WIDGET_H

#include <QtWidgets>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlField>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    bool initDb();
private:
    Ui::Widget *ui;
    QSqlDatabase db;
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"

#if 1
const QString CRESQL1 = "create table test1(id integer, age integer, name varchar)";
const QString CRESQL2 = "create table test2(id integer, size integer, data varchar)";
#else
const QString CRESQL1 = "create table test1(id integer, age integer, name varchar, title integer)";
const QString CRESQL2 = "create table test2(id integer, size integer, data varchar, type integer, value varchar)";
#endif

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    initDb();
}

Widget::~Widget()
{
    delete ui;
}

bool Widget::initDb()
{
    db = QSqlDatabase::addDatabase("QSQLITE","test_sqlite_connect");
    QString projectDir = QCoreApplication::applicationDirPath();
    QStringList tmpRootDirlist = QString(projectDir).split("/");
    if(tmpRootDirlist.size() >= 2){
        tmpRootDirlist.removeLast();
        tmpRootDirlist.removeLast();
    }

    QString userDataPath =  QApplication::applicationDirPath()+"/library";

    QString dbpath = userDataPath + "/test_sqlite.db";

    QDir userDataDir(userDataPath);
    if(!userDataDir.exists()){
        userDataDir.mkpath(userDataPath);
    }

    qDebug() << __FUNCTION__ << __LINE__ << " ============>>>>    " << dbpath;

    db.setDatabaseName(dbpath);
    db.setPassword("123456");
    db.setHostName("127.0.0.1");
    db.setUserName("CSDN");

    if (!db.open()){
        perror(db.lastError().text().toUtf8().data());
        return false;
    }

    QStringList tables = db.tables();
    qDebug() << __FUNCTION__ << __LINE__ << tables;

    QSqlQuery q(db);
    QStringList sqlist( QStringList() << CRESQL1 << CRESQL2);
    QStringList tablelist( QStringList() << "test1" << "test2");
    for (int i = 0; i < tablelist.size(); ++i)
    {
        QString tableName = tablelist.at(i);
        if (tables.contains(tableName))
        {
            QString selectSql = QString("select * from %1;").arg(tableName);
            if (!q.exec(selectSql))
            {
                perror(q.lastError().text().toUtf8().data());
                continue;
            }
            QStringList oldtitles;
            for (int j = 0; j < q.record().count(); ++j)
            {
                auto type = q.record().field(j).type();
                auto title = q.record().fieldName(j);
                oldtitles.append(title);
            }
            QString newtitle = sqlist.at(i);
            newtitle = newtitle.mid(newtitle.indexOf("(")+1,newtitle.indexOf(")")-newtitle.indexOf("(")-1);
            newtitle.remove("\n");
            QStringList newtitles = newtitle.split(",");
            if (newtitles.size() != oldtitles.size())
            {
                for (int k = oldtitles.size(); k < newtitles.size(); ++k)
                {
                    QString title = newtitles.at(k);
                    if (title.size())
                    {
                        if (title.mid(0,1) == " ")
                        {
                            title = title.mid(1,title.size());
                        }
                        title = title.split(" ").first();
                        if (!oldtitles.contains(title))
                        {
                            QString sql = QString("ALTER TABLE %1 ADD COLUMN %2").arg(tableName).arg(newtitles.at(k));
                            qDebug()<<__FUNCTION__<<__LINE__<<"数据库添加新字段"<<sql;
                            if(!q.exec(sql))
                            {
                                perror(q.lastError().text().toUtf8().data());
                                continue;
                            }
                        }
                    }
                }
            }
        }
        else
        {
            if(!q.exec(sqlist.at(i)))
            {
                perror(q.lastError().text().toUtf8().data());
                continue;
            }
        }
    }

    return true;
}


旧表:
在这里插入图片描述

const QString CRESQL1 = “create table test1(id integer, age integer, name varchar)”;
const QString CRESQL2 = “create table test2(id integer, size integer, data varchar)”;
改为
const QString CRESQL1 = “create table test1(id integer, age integer, name varchar, title integer)”;
const QString CRESQL2 = “create table test2(id integer, size integer, data varchar, type integer, value varchar)”;
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值