【问题标题】:Qt - How to use SQL SELECT COUNT with parameters?Qt - 如何使用带参数的 SQL SELECT COUNT?
【发布时间】:2019-01-12 21:02:54
【问题描述】:

我正在用 QT 编写程序,但在编写 SQL 查询 Select 时遇到问题。 我有一个简单的表,其中包含以下列:ID、name_or_nickname、surname、职业。我想在查询中使用 3 个变量:

QString name = "Peter";
QString surname = "Smith"; 
QString occupation = "New York";

我想使用这些变量运行这个查询:

 QSqlDatabase sql;                                                 
 QSqlQuery query(sql);
 QString execute = "SELECT COUNT(name) FROM table1 WHERE name_or_nickname='?' AND surname='?' AND occupation='?';";
        query.prepare(execute);
        query.bindValue(0, name);
        query.bindValue(1, _surname);
        query.bindValue(2, _occupation);
        query.exec();

        if (query.next()) 
        {
            rows= query.value(0).toInt();
            return true;
        } 
        else 
        {
            qDebug() << query.lastError();
            return false;
        }

但是它不起作用并且 isActive() 函数返回 false,因此查询有问题 - 可能与括号有关。你能告诉我一个例子我应该如何处理它?先感谢您!

================================================ ==============================

我在这里发布必要的代码:

MainWindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <person.h>
#include <QMainWindow>
#include <QString>
#include <QtDebug>
#include <QtSql>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_1_clicked();

private:
    Ui::MainWindow *ui;

    QSqlDatabase sql;
    bool open_or_not;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    sql = QSqlDatabase::addDatabase("QSQLITE", "db");
    sql.setDatabaseName("E:\\folder\\database.sqlite3");
    sql.close(); // this was called beacuse of the problem with first query
    sql.open();

    QSqlQuery query(sql);
    QString execute = "CREATE TABLE IF NOT EXISTS table1 (id INTEGER UNIQUE PRIMARY KEY, name_or_nickname TEXT, surname TEXT, occupation TEXT);";
query.exec(execute);
    qDebug() << "isActive: CREATING TABLE" << query.isActive();
    query.clear();

    open_or_not = sql.open();

}

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

void MainWindow::on_pushButton_1_clicked()
{
    if(open_or_not)
    {
        Person person1(_sql, Johnny, Walker, California, this);
        bool result = false;
        result = person1.search_in_database();
        qDebug() << result;
    }
}

Person.h:

#ifndef PERSON_H
#define PERSON_H

#include <QNetworkRequest>
#include <QNetworkReply>
#include <QtDebug>
#include <QDebug>
#include <QJsonDocument>
#include <QtSql>

namespace Ui {
class Person;
}

class Person : public QDialog
{
    Q_OBJECT

public:
    explicit Person(QSqlDatabase & sql, QString name_or_nickname, QString surname, QString occupation, QWidget *parent);
    ~Person();

    bool search_in_table();

private:
    Ui::Person *ui;

    QSqlDatabase sql;
    QString name_or_nickname;
    QString surname;
    QString occupation;


};

#endif // PERSON_H

Person.cpp:

#include "person.h"
#include "ui_person.h"


Person::Person(QSqlDatabase & sql, QString name_or_nickname, QString surname, QString occupation, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Person)
{
    ui->setupUi(this);

    this->sql = sql;
    this->name_or_nickname = name_or_nickname;
    this->surname = surname;
    this->occupation = occupation;

}

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

bool Person::search_in_table()
{
    QSqlQuery query(sql);

    int rows = 0;
    QString name = this->name_or_nickname;
    QString _surname = this->surname;
    QString _occupation = this->occupation;

    QString execute = "SELECT COUNT(name) FROM table1 WHERE name_or_nickname='?' AND surname='?' AND occupation='?';";
    query.prepare(execute);
    query.bindValue(0, name);
    query.bindValue(1, _surname);
    query.bindValue(2, _occupation);
    query.exec();

    if (query.next()) 
    {
        rows= query.value(0).toInt();
        return true;
    } 
    else 
    {
        qDebug() << query.lastError();
        return false;
    }
}

Main.cpp:

#include "mainwindow.h"
#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

【问题讨论】:

  • 在执行 QString 时在行尾添加了缺少的括号,实际上仍然不起作用...
  • 我看到你用QSqlDatabase _sql;但是你在哪部分设置配置并打开连接?`
  • 好吧,我有 2 个类 - MainWindow 和 Person。我在 MainWindow 的构造函数中设置配置,并在 MainWindow 类中创建 Person 的对象时传递 _sql 参数。所以我认为一切都应该正常
  • 好吧,正如您在问题中没有向我指出的那样,这是可能导致错误的一点。
  • 但是什么会导致这个问题呢?我什至已经尝试通过引用传递这个参数,但它没有改变任何东西。还有其他建议吗?

标签: qt sqlite qstring qsqlquery qsqldatabase


【解决方案1】:

更好地使用带参数的查询来防止SQL中的不同类型转换问题

QString execute = "SELECT COUNT(name) FROM table1 WHERE surname=? AND occupation=?;";
QSqlQuery query;
query.prepare(execute);
query.bindValue(0, surname);
query.bindValue(1, occupation);
query.exec();
if (query.next()) {
    rows= query.value(0).toInt();
} else {
    qDebug() << query.lastError(); //check your error here
}

【讨论】:

  • 好吧,我收到了这个:QSqlError("", "Parameter count mismatch", "")
  • 你有什么建议?
  • 查询看起来不错...也许尝试引用您的字段名称。像“SELECT COUNT('name')...”。也许您使用的 DBMS 具有称为 name 的系统关键字
  • 说实话我只是把这个变量的简单名称放了,只是为了让你看看它是如何工作的——全名是:name_or_nickname,所以我认为 DBMS 不能知道这个 ;-)还有其他想法吗?
  • 好的,我已经解决了这个问题。非常感谢您的帮助:-)
【解决方案2】:

试试这个代码:

QSqlDatabase _sql;                                                 
QSqlQuery _query(_sql);
QString execute_stat = "SELECT COUNT(name) FROM table1 WHERE surname='%1' AND 
occupation='%2';";

_query.prepare(execute_stat.arg(surname, occupation));
q.exec();
int rows= 0;
if (q.next()) {
    rows= q.value(0).toInt();
}

【讨论】:

  • 它没有帮助。 isActive() 仍然返回 false :-( 你还有什么建议?
  • 您不会使用 isActive() 来知道名称的计数,该计数将存储在 rows 变量中
  • 我知道,我先用它看看查询是否可以
【解决方案3】:

你忘了在语句末尾加上双引号

你的:

QString execute = "SELECT COUNT(name) FROM table1 WHERE surname='%1' AND occupation='%2';

应该是:

QString execute = "SELECT COUNT(name) FROM table1 WHERE surname='%1' AND occupation='%2';"

【讨论】:

  • 是的,当然,但我只在 StackOverflow 上犯了这个错误。在我的程序中,我有它。你有什么建议?
  • 我添加了这些括号,但它不起作用。你有什么建议?
  • 好的,我已经解决了这个问题。非常感谢您的帮助:-)
【解决方案4】:

说实话,我不知道为什么上述建议的方法都没有起作用。

但是,最简单的版本对我有用:

QString execute = "SELECT COUNT(*) FROM table1 WHERE (name_or_nickname='" + name + "') AND (surname='" + surname + "') AND (occupation='" +occupation + "') ;";

感谢您的所有帮助。

【讨论】:

    猜你喜欢
    • 2021-03-17
    • 1970-01-01
    • 2015-04-18
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    相关资源
    最近更新 更多