C++ QSqlQuery是否插入完整结构而不是单个字段?

C++ QSqlQuery是否插入完整结构而不是单个字段?,c++,mysql,qt,qt5,qsqlquery,C++,Mysql,Qt,Qt5,Qsqlquery,在MySQL数据库中可以实现如下插入操作,即: QSqlQuery query; query.prepare("INSERT INTO person (id, forename, surname) " "VALUES (:id, :forename, :surname)"); query.bindValue(":id", 1001); query.bindValue(":forename", "Bart"); query.bindValue(":surname", "

在MySQL数据库中可以实现如下插入操作,即:

QSqlQuery query;
query.prepare("INSERT INTO person (id, forename, surname) "
              "VALUES (:id, :forename, :surname)");
query.bindValue(":id", 1001);
query.bindValue(":forename", "Bart");
query.bindValue(":surname", "Simpson");
query.exec();
它起作用了。但它很脆弱,不是吗?如果数据库程序员在MySQL脚本中更改列名,即将姓氏更改为lastname,则当列名不匹配时,它将停止工作,因为名称是硬编码的

我想到的是改变整个机制,这样就不用插入单个字段,而是插入一个大对象,也许应该插入一个由单个字段组成的结构。然后,在db端,字段应被拆分回一组字段,即使用视图或触发器

我走的方向对吗


我非常感谢您对这个问题的一般性评论。

当然,有一种方法,但您必须确保表的结构和列的含义不会改变,并且您的查询中有每一列的数据要插入

首先,您必须选择表的所有信息:

SELECT c.column_name FROM information_schema.columns c 
WHERE c.table_name = 'some_table_name' 
ORDER BY c.ordinal_position ASC
其次,您的代码可以这样更改。我使用的是通用方法,这意味着您已经知道数据:

QList<QVariant> valuesList { QVariant(1), QVariant("Bart"), QVariant("Simpson") }; 
QList<QPair<QString, QVariant>> varList;
QSqlQuery query;
query.exec("SELECT @rownum := @rownum + 1 AS row_num, c.column_name 
            FROM information_schema.columns c, (SELECT @rownum := -1) r
            WHERE c.table_name = 'some_table_name' 
            ORDER BY c.ordinal_position ASC");
while(query.next())
    colList << QPair<QString, QString>(query.value(1).toString(), 
               valuesList.at(query.value(0).toInt()));

QString queryString = "INSERT INTO person (%1) "
                      "VALUES (%2)";

QString insertColsString;
QString bindColsString;

for(int i = 0; i < colList.size(); i++) {
    insertColsString += colList.at(i).first + ", ";
    bindColsString += ":" colList.at(i).first + ", ";
}

if(!insertColsString.isEmpty()) {
    insertColsString.chop(2);
    bindColsString.chop(2);
}

query.prepare(queryString.arg(insertColsString, bindColsString));

for(int i = 0; i < colList.size(); i++)
    query.bindValue(":" + colList.at(i).first, colList.at(i).second);

query.exec();

当然,有一种方法,但您必须确保表的结构和列的含义不会改变,并且您的查询具有要插入的每个列的数据

首先,您必须选择表的所有信息:

SELECT c.column_name FROM information_schema.columns c 
WHERE c.table_name = 'some_table_name' 
ORDER BY c.ordinal_position ASC
其次,您的代码可以这样更改。我使用的是通用方法,这意味着您已经知道数据:

QList<QVariant> valuesList { QVariant(1), QVariant("Bart"), QVariant("Simpson") }; 
QList<QPair<QString, QVariant>> varList;
QSqlQuery query;
query.exec("SELECT @rownum := @rownum + 1 AS row_num, c.column_name 
            FROM information_schema.columns c, (SELECT @rownum := -1) r
            WHERE c.table_name = 'some_table_name' 
            ORDER BY c.ordinal_position ASC");
while(query.next())
    colList << QPair<QString, QString>(query.value(1).toString(), 
               valuesList.at(query.value(0).toInt()));

QString queryString = "INSERT INTO person (%1) "
                      "VALUES (%2)";

QString insertColsString;
QString bindColsString;

for(int i = 0; i < colList.size(); i++) {
    insertColsString += colList.at(i).first + ", ";
    bindColsString += ":" colList.at(i).first + ", ";
}

if(!insertColsString.isEmpty()) {
    insertColsString.chop(2);
    bindColsString.chop(2);
}

query.prepare(queryString.arg(insertColsString, bindColsString));

for(int i = 0; i < colList.size(); i++)
    query.bindValue(":" + colList.at(i).first, colList.at(i).second);

query.exec();

那么,你是在寻找一些实现方法,你可以在DB中从姓氏到姓氏改变列,然后C++代码会自动知道应该进入姓氏的值现在进入了LASTEND,而C++的边上没有任何变化?但是,既然你提出了这个相关的问题,你可能对你自己的问题有了一个答案,这个答案与我的问题非常接近——编辑这个问题是为了让我的方法更加清晰,在这种情况下,我对你的方法感兴趣。您知道如何卸载查询并在运行时加载它吗?对不起,事实上我问了我的问题,因为我认为没有办法实现它。也许这里有人可以纠正我。我认为没有任何方法可以让C++代码知道,没有任何改变,LaSTNEXT列取代了姓氏列。我真的认为,DB模式的任何更改都会对使用它的C++代码产生影响,不管你做什么。所以,你在寻找实现的方式,在这里你可以将数据库中的姓氏改为姓氏,然后C++代码会自动知道,应该进入姓氏的值现在进入了LASTEND,而C++的边上没有任何变化?但是,既然你提出了这个相关的问题,你可能对你自己的问题有了一个答案,这个答案与我的问题非常接近——编辑这个问题是为了让我的方法更加清晰,在这种情况下,我对你的方法感兴趣。您知道如何卸载查询并在运行时加载它吗?对不起,事实上我问了我的问题,因为我认为没有办法实现它。也许这里有人可以纠正我。我认为没有任何方法可以让C++代码知道,没有任何改变,LaSTNEXT列取代了姓氏列。我真的认为,DB模式的任何改变都会对使用C++的代码产生影响,无论你做什么。