Qt:将SQL查询的结果保存在变量中,在SQL查询中使用C ++变量

时间:2015-05-10 08:25:56

标签: c++ mysql qt

我的项目是编写一个简单的ShopApp。一个功能是检查是否有足够的库存,以便客户可以购买所需数量的他想要购买的东西。函数看起来像(cartstd::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()

1 个答案:

答案 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)实际访问记录之前,您需要进行此调用。