我的项目是编写一个简单的ShopApp。一个功能是检查是否有足够的库存,以便客户可以购买所需数量的他想要购买的东西。函数看起来像(cart
是std::vector<product>
而Pid代表产品ID):
bool sqlfunctions::checkStock(){
QSqlQuery query;
int diff, stock;
for(iter cursor = cart.begin();cursor!=cart.end();cursor++){
query.prepare("SELECT stock FROM products WHERE id = cursor->getPid()");
query.exec();
// Need to save result of query into variable stock
stock = ??;
diff = stock - cursor->getAmount;
if(diff < 0){
return false;
}
}
return true;
}
显然这个函数不起作用,因为cursor-&gt; getPid()没有被执行,因为它是一个字符串。所以这里的问题是如何将c ++变量插入sql-query ?在常规C ++中我会使用一些swprintf_s
函数。那么query.prepare(swprintf_s(...))
是个好主意吗?
第二件事是,因为query.exec()
和query.prepare()
都是布尔值,返回真或假,取决于成功,我怎么能存储
c ++变量中的查询结果?
请注意,我是Qt的SQL和SQL新手。我用的是QT5。
我已经尝试阅读有关QSqlQuery
类及其功能的文档,BindValue()
和addBindValue()
似乎很有趣。但是我真的不明白它们是如何工作的。
修改
所以现在我已经有一个最小的例子,尽管已经接受了接受的答案,但还没有成功。但是编译器没有给我任何警告或错误:
void MainWindow::on_ButtonSQL_clicked()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("...");
db.setDatabaseName("...");
db.setUserName("...");
db.setPassword("...");
db.setPort(3306);
db.open();
QMessageBox msgBox;
if (db.open()) {
msgBox.setText("It works :)");
msgBox.exec();
}
else {
msgBox.setText("No connection.");
msgBox.exec();
}
QSqlQuery query(db);
// This query worked!
query.exec("INSERT INTO users (id, username, balance) VALUES(25, 'someName', 10000)");
// initialize someNumber to check later, whether it was processed correctly.
int id = 2, someNumber = 20;
query.prepare("SELECT stock FROM products WHERE id = :myid");
query.bindValue(":myid", id);
query.exec();
QString idValue = query.boundValue(0).toString();
someNumber = query.value(0).toInt();
msgBox.setText("The stock is: "+QString::number(someNumber)+"\nThe placeholder has the value: "+idValue);
msgBox.exec();
}
最后一个msgBox的预期msgBox是:
The stock is: 100
The placeholder value is: 2
输出实际上是:
The stock is: 0
The placeholder value is: 2
如果我尝试选择一个字符串(例如productName),例如QString myProductName = query.value(0).toString()
(以及代码中的相应更改),则返回将是一个空字符串。
**已解决:**请在接受的答案中查看Floris的评论。我错过了query.next()
。
答案 0 :(得分:6)
实际上非常直接:
QSqlQuery query;
query.prepare("Select stock from products where id = :input");
query.bindValue(":input", cursor->getPid());
query.exec();
将值绑定到字符串中的参数。参数遵循以下格式::name
。还有位置绑定,它按照它看到的顺序绑定?。
QSqlQuery query;
query.prepare("Select stock from products where id = ?");
// No need for an identifier
query.bindValue(cursor->getPid());
query.exec();
要迭代从查询中获取的记录,您可以执行以下操作:
QSqlQuery query;
query.prepare("SELECT stock FROM employee WHERE id = ?");
query.bindValue(cursor->getPid());
query.exec();
if (query.next()) {
int stock = query.value(0).toInt();
// You could store the information you obtain here in a vector or something
}
您也可以将prepare语句放在for循环之外。如果您对迭代多个记录(来自select语句)感兴趣,可以使用while语句替换if语句。
关于QSqlQuery::next()
:
检索结果中的下一条记录(如果有),并将查询定位在检索到的记录上。请注意,结果必须处于活动状态,并且isSelect()必须在调用此函数之前返回true,否则它将不执行任何操作并返回false。
As taken from QSqlQuery。在使用.value(int)
实际访问记录之前,您需要进行此调用。