2015-11-14 107 views
0

我具有以下的Qt/C++方法:SELECT LAST_INSERT_ID()返回零

quint64 UeBillModel::ueGetNextPickupIndex() 
{ 
    quint64 pickupIndex=0; 

    if(!this->ueDatabase().isOpen()) 
    { 
     this->ueConnectToDatabase(); 
    } // if 

    this->setQuery(UePosDatabase::UeSqlQueries::UeInsertNewBill::SQL_QUERY_CALC_NEXT_PICKUP_NUMBER, 
        this->ueDatabase()); 

    if(this->lastError().isValid()) 
    { 
     qDebug() << this->lastError(); 

     pickupIndex=-1; 
    } 
    else 
    { 
     this->setQuery(UePosDatabase::UeSqlQueries::UeInsertNewBill::SQL_QUERY_GET_NEXT_PICKUP_NUMBER, 
         this->ueDatabase()); 

     if(this->lastError().isValid()) 
     { 
      qDebug() << this->lastError(); 

      pickupIndex=-1; 
     } 
     else 
     { 
      pickupIndex=this->record(0).value(0).toUInt(); 
     } // if 
    } // if 

    return pickupIndex; 
} // ueGetNextPickupIndex 

一旦執行該方法時,它返回0。正如你所看到的,它執行兩個查詢:

static const QString SQL_QUERY_CALC_NEXT_PICKUP_NUMBER="UPDATE "+UePosDatabase::UeTableNames::TABLE_PICKUP_NUMBER+ " SET ID = LAST_INSERT_ID(ID+1)"; 
    static const QString SQL_QUERY_GET_NEXT_PICKUP_NUMBER="SELECT LAST_INSERT_ID()"; 

有了第一個,我更新內表PICKUP_NUMBER,並與第二我想最後得到插入ID的申請。如果我直接在mysql服務器內部執行這兩條語句,我會得到正確的值。那麼爲什麼方法返回0

回答

1

首先,MYSQL中的LAST_INSERT_ID()函數具有連接範圍。這意味着,只要您關閉以前的連接,您將失去對該值的訪問權限。這就是爲什麼,如果你打開一個全新的連接,那麼在你執行一個插入操作之前沒有任何價值。

其次,它不是一個好主意,可以存儲此值,也可以嘗試計算任何值,除非您需要將其用作另一個表中的外鍵。

在插入時間和使用最後一個ID之間的時間內,可能有另一個用戶在您的表格中插入了另一條記錄,導致存儲的ID冗餘,並使您處於數字衝突的風險中。

第三,QtSqlQuery類具有恰好爲此目的一個函數getLastInsertId()(只要數據庫連接保持打開),並且可用於支持該功能的任何數據庫,通過檢查的QSqlDriver::hasFeature(QSqlDriver::lastInsertId)

+0

返回值來確定有用的職位,但我應該如何以「正確」的方式解決這種情況? – KernelPanic

+0

這完全取決於你爲什麼要將價值存儲在第一位。正如我在文章中所說的,只有在您需要外鍵時才應該這樣做。 – RobbieE