今天在开发QT时遇到了如下问题,困扰了很久才解决,记录一下以便日后遇见相同问题时不至于毫无头绪。
先上代码:
void BaseSql::insertSim(const QMap<QString, QVariant> ¶ms, const QString &tableName)
{
db_sim.transaction();
QSqlQuery query(databaseMap.value(SIM_MODE));
QString keys;
foreach (QString key, params.keys()) {
keys.append(key).append(",");
}
keys.chop(1);
qDebug() << "keys = " << keys;//这里的顺序不是params插入的原始顺序,是经过排序之后的顺序
if(tableName == TmoGroupContactTable || tableName == DmoGroupContactTable)
{
if(getSimdealNumber()==1)
{
//首次处理
m_sql += QString("insert into %1 (%2) select ").arg(tableName).arg(keys);
m_sql += QString("%1, '%2', '%3', %4, %5, '%6' ").arg(params["id"].toInt()).arg(params["name"].toString()).arg(params["num"].toString())\
.arg(params["numType"].toInt()).arg(params["airAddr"].toInt()).arg(params["pinyin"].toString());
}
else
{
m_sql += QString("union all select ");
m_sql += QString("%1, '%2', '%3', %4, %5, '%6' ").arg(params["id"].toInt()).arg(params["name"].toString()).arg(params["num"].toString())\
.arg(params["numType"].toInt()).arg(params["airAddr"].toInt()).arg(params["pinyin"].toString());
}
}
else if(tableName == subgroupTableName)
{
if(getSimdealNumber()==1)
{
//首次处理
m_sql += QString("insert into %1 (%2) select ").arg(tableName).arg(keys);
m_sql += QString("%1, %2, ?, '%3', %4 ").arg(params["id"].toInt()).arg(params["memNum"].toInt()).arg(params["name"].toString())\
.arg(params["type"].toInt());
bytearraylist.append(params["member"].toByteArray());
}
else
{
m_sql += QString("union all select ");
m_sql += QString("%1, %2, ?, '%3', %4 ").arg(params["id"].toInt()).arg(params["memNum"].toInt()).arg(params["name"].toString())\
.arg(params["type"].toInt());
bytearraylist.append(params["member"].toByteArray());
}
}
else if(tableName == subgroupListTableName)
{
if(getSimdealNumber()==1)
{
//首次处理
m_sql += QString("insert into %1 (%2) select ").arg(tableName).arg(keys);
m_sql += QString("%1, %2 ").arg(params["id"].toInt()).arg(params["subgroupId"].toInt());
}
else
{
m_sql += QString("union all select ");
m_sql += QString("%1, %2 ").arg(params["id"].toInt()).arg(params["subgroupId"].toInt());
}
}
if(getSimdealNumber()==getSimhandleNumber())
{
//sql语句注入完毕
m_sql.chop(1);
m_sql.append(";");
Log(m_sql);
if(tableName == subgroupTableName)
{
query.prepare(m_sql);
foreach(QByteArray byteArray, bytearraylist)
{
query.addBindValue(byteArray);
}
exec(query,m_sql);
}
db_sim.commit();
m_sql = "";
setSimhandleNumber(0);
setSimdealNumber(0);
}
}
执行上述代码后,打印报错QSqlError(-1, "Parameter count mismatch", "")
。错误内容是“参数个数不匹配”,一开始百思不得其解,后来经过查阅资料得知,在m_sql
语句中有占位符?
时,使用query.prepare(m_sql)
和query.addBindValue(byteArray)
绑定占位符之后,执行exec(query,m_sql);
这个函数的时候,是不可以带上m_sql
这个具体语句作为参数的。如果不使用占位符,只用到%1
配合.arg()
的话,则在执行exec(query,m_sql);
时是需要带上m_sql
这个具体语句作为参数。
因此,上述代码中的exec(query,m_sql);
改为exec(query);
就可以成功执行sql插入语句了。