查看下列程序问题#include "database.h" #include <QSqlQuery> #include <QVariant> Database::Database(QObject *parent):QObject(parent) { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("./database/user.db"); db.open(); db.exec("create table if not exists Person(ID integer primary key autoincrement, name varchar(30), pwd varchar(30))"); } Database::~Database() { db.close(); } bool Database::open() { int ret = db.open(); if(ret) return true; else return false; } void Database::close() { db.close(); } void Database::creat() { QSqlQuery query; } int Database::no_res(char* sql) { QSqlQuery query; int ret = query.exec(sql); return ret; } int Database::getres(char* sql) { QSqlQuery query; query.exec(sql); while(query.next()) { int ret = query.value(0).toInt(); return ret; } }
时间: 2024-01-21 13:03:56 浏览: 31
这段程序中存在一些问题:
1. 函数creat()没有现任何功能,可以考虑删除。
2. 函数no_res()和getres()中的char*类型的参数不够安全,建议改为QString类型。
3. 函数getres()可能存在问题,因为只返回了查询结果集中的第一行第一列数据,如果结果集中有多行数据,其他行数据将会被忽略。可以考虑修改为返回查询结果集中所有数据的列表或数组。
4. 在函数open()中,如果数据库打开失败,应该输出错误信息以便进行调试。
5. 在函数getres()中,如果查询结果集为空,没有返回值,可以考虑添加一个默认返回值,如-1或0。
6. 在析构函数中,应该先判断数据库是否已经关闭,如果未关闭才进行关闭操作。
相关问题
改进代码#include "database.h" #include <QSqlQuery> #include <QVariant> #include <QDebug> Database::Database(QObject *parent):QObject(parent) { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("./database/user.db"); db.open(); db.exec("create table if not exists Person(ID integer primary key autoincrement, name varchar(30), pwd varchar(30))"); } Database::~Database() { db.close(); } int Database::no_res(char* sql) { QSqlQuery query; int ret = query.exec(sql); return ret; } int Database::login(char* sql) { QSqlQuery query; query.exec(sql); while(query.next()) { int ret = query.value(0).toInt(); return ret; } return 0; }
这段代码看起来已经很不错了,不过还有一些可以改进的地方:
1. 使用 QString 替代 char* 类型,更加方便和安全。
2. 在 login 函数中,如果查询结果为空,应该返回 -1 表示出错,而不是返回 0。
3. 可以在函数中添加一些错误处理机制,比如在打开数据库时检查是否成功打开,如果出错应该输出错误信息。
改进后的代码如下:
```
#include "database.h"
#include <QSqlQuery>
#include <QVariant>
#include <QDebug>
Database::Database(QObject *parent):QObject(parent)
{
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("./database/user.db");
if(!db.open())
{
qDebug() << "Error: Failed to connect database." << db.lastError();
}
else
{
QSqlQuery query;
query.exec("create table if not exists Person(ID integer primary key autoincrement, name varchar(30), pwd varchar(30))");
}
}
Database::~Database()
{
db.close();
}
int Database::no_res(QString sql)
{
QSqlQuery query;
int ret = query.exec(sql);
if(!ret)
{
qDebug() << "Error: " << query.lastError();
}
return ret;
}
int Database::login(QString sql)
{
QSqlQuery query;
query.exec(sql);
if(query.next())
{
int ret = query.value(0).toInt();
return ret;
}
return -1;
}
```
#include "database.h" #include <QSqlQuery> #include <QVariant> Database::Database(QObject *parent):QObject(parent) { db = QSqlDatabase::addDatabase("QSQLITE"); db.setDatabaseName("./database/user.db"); db.open(); db.exec("create table if not exists Person (id int primary key autoincrement, name varchar(30), pwd varchar(30))"); } Database::~Database() { db.close(); } bool Database::open() { int ret = db.open(); if(ret) return true; else return false; } void Database::close() { db.close(); } int Database::no_res(char* sql) { QSqlQuery query; int ret = query.exec(sql); return ret; } int Database::getres(char* sql) { QSqlQuery query; query.exec(sql); int ret = query.value(0).toInt(); return ret; }问题
这段代码是一个简单的 Qt 数据库操作的示例。其中,Database 类是一个封装了 QSqlDatabase 和 QSqlQuery 的类,提供了打开、关闭数据库、执行 SQL 语句等基本操作。这里提出两个问题:
1. 在 open() 函数中,如果 db.open() 返回 false,应该返回 false,而不是返回 true。因为 db.open() 返回 false 表示数据库未能成功打开,返回 true 表示数据库已经成功打开。
2. 在 no_res() 和 getres() 函数中,使用 char* 类型的参数作为 SQL 语句传入 QSqlQuery::exec() 函数。这样的写法存在 SQL 注入攻击的风险。应该使用 QSqlQuery::prepare() 函数将 SQL 语句和参数分离,以避免 SQL 注入攻击。例如:
```
int Database::no_res(const QString& sql, const QVariantList& params)
{
QSqlQuery query;
query.prepare(sql);
for (int i = 0; i < params.size(); ++i) {
query.addBindValue(params.at(i));
}
return query.exec();
}
int Database::getres(const QString& sql, const QVariantList& params)
{
QSqlQuery query;
query.prepare(sql);
for (int i = 0; i < params.size(); ++i) {
query.addBindValue(params.at(i));
}
query.exec();
int ret = query.value(0).toInt();
return ret;
}
```
在这种写法中,SQL 语句和参数被分离开来,参数通过 QVariantList 传递,而且使用了 QSqlQuery::prepare() 和 QSqlQuery::addBindValue() 函数,可以避免 SQL 注入攻击的风险。
相关推荐
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://img-home.csdnimg.cn/images/20210720083646.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![doc](https://img-home.csdnimg.cn/images/20210720083327.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)