在将1023行数据插入mysql数据库

时间:2016-03-07 21:19:29

标签: c++ mysql qt

我正在为pfsense生成的优惠券编写凭证管理系统。该程序相对简单,因为它需要导入pfsense生成的csv文件,将它们插入数据库,然后能够将它们打印为收据。我已经编写了将数据插入数据库的函数,但是当我运行它时,程序会挂起一些并显示没有响应。是否有任何方法可以使程序等待,如暂停,执行完成而不说它已停止响应?任何帮助,将不胜感激。我的功能如下:

void MainWindow::updateVouchers()
{
int insertions = 0;//used to keep track of total number of successful insertions into database
int total = 0; //used to keep track of how many lines of codes need to be inserted

//check if a the user selected a valid csv file and gave a valid voucher expiration time
if (im_FileName.isNull() || im_FileName.isEmpty() || voucherTime <= 0 )
{
    ui->statusBar->showMessage("Please select a voucher file to import and enter a valid time",5000);
    return;
}

{
    QSqlDatabase dbcon = QSqlDatabase::addDatabase("QMYSQL","updateconnection");

    QString host = "localhost";
    QString dbname = "xxxxxxx";
    QString uname = "admin";
    QString pword = "xxxxxx";
    int port = 3306;
    dbcon.setHostName(host);
    dbcon.setDatabaseName(dbname);
    dbcon.setUserName(uname);
    dbcon.setPassword(pword);
    dbcon.setPort(port);


    if ( !dbcon.open() ) //condition used to check if database connection was bad
    {
        QSqlError error = dbcon.lastError();
        QMessageBox::warning(this,"Error Connecting to database",
                             QString("There was an error while connecting to %1, the error is %2").arg(dbname).arg(error.text()),
                             QMessageBox::Ok,QMessageBox::Cancel);
    }
    else //if connection to database was good write vouchers to database
    {
        QFile theFile(im_FileName); //create a file with the csv which was imported
        int count = 0;
        QString line = QString();

        //check to see if the file can be opened
        if ( !theFile.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            QMessageBox::warning(this,tr("Error Opening the file!"),QString("There was an erro opening file %1").arg(im_FileName),QMessageBox::Ok,QMessageBox::Close);
        }
        else //if the file was opened successfully, create a stream and update the vouchers
        {
            //ensure that a valid filename and voucher time has been specified

            QTextStream stream(&theFile);
            QSqlQuery query(dbcon);

            //loop through the stream reading one line at a time
            while ( !stream.atEnd() )
            {
                count++;
                line = stream.readLine();
                if ( count > 7 && !line.isEmpty() && !line.isNull() ) //make sure the line read has something in it
                {
                    QString newLine( line.remove(QRegExp("[\\s\"]") ) );
                    query.prepare("INSERT INTO vouchers (code, valid_time, isUsed, isPrinted)" "VALUES (?, ?, ?, ?)");
                    //query.prepare("INSERT INTO vouchers (code, valid_time, isUsed, isPrinted)" "VALUES (:code, :time, :used, :printed");
                    query.bindValue(0,newLine);
                    query.bindValue(1,voucherTime);
                    query.bindValue(2,false);
                    query.bindValue(3,false);
                    bool status = query.exec();
                    total++; //for each line of voucher code that is valid, update the total number of lines int the file
                    if ( status == true ) { insertions++; } //if code was entered into database okay, update amount of good insertions
                }
            }//end of while loop

        }//end of file open else

    }//end of database open else
    dbcon.close();
}

QSqlDatabase::removeDatabase("updateconnection");
ui->statusBar->showMessage(QString("%1 of %2 voucher codes were successfully inserted!").arg(insertions).arg(total),5000);

}

我犯了什么错误?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您是否尝试将query.prepare()行移到while循环之上(上方)?看起来您正在为每条记录准备声明。这应该是不必要的,因为可重用性是准备语句存在的原因。

此外,即使重新使用准备好的声明,您仍然执行了超过1,000次操作。这可能只是一个缓慢的操作。您可能需要考虑将您的数据库代码放入另一个线程以保持UI线程的响应。

我知道您的示例代码显示您的服务器位于localhost。如果不是,我会重新声明一个单独的数据库线程是可取的 - 许多往返服务器的往返都可以真正加起来。

最后,MySQL有两个你可以使用的工具。一个是extended inserts。您可以使用扩展插入语法构建SQL命令字符串,以便一次性插入批量记录(如果这样做,请确保处理引用值)。第二个是LOAD DATA命令;用于导入数据。