2014-12-29 123 views
1

我一整天都在苦苦掙扎。我讀過無數帖子,嘗試了所有建議,但沒有任何作用。PDO SQLite無法更新記錄:「數據庫已被鎖定」

這是我的PHP代碼:

try { 
$db = new PDO('sqlite:test.db'); 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$result = $db->query('SELECT * FROM v_test'); 

foreach ($result as $row) { 
    echo $row['column1'] . " | " . $row['column2'] . "<br>"; 

    /************************************** 
    * Update table      * 
    **************************************/ 
    if (!$db->exec("update test set column2 = date('now') where column1 ='" . $row['column1'] . "';") === TRUE) { 
    echo "Cannot update date:" . $db->lastErrorMsg(); 
    $db = null; 
    exit; 
    } 
} 

/************************************** 
* Close db connections    * 
**************************************/ 
$db = null; 
} 
catch(PDOException $e) { 
    echo "PDOException: " . $e->getMessage() . "<br>"; 

    /*** show the error info ***/ 
    foreach($db->errorInfo() as $error) 
    { 
    echo $error.'<br />'; 
    } 

    $db = null; 
} 

我運行PHP v5.3.3。 只需選擇後的循環,我可以從表中獲取正確的值,這樣我就可以訪問與我的腳本位於同一文件夾中的數據庫。該文件夾有0777權限,數據庫和腳本都有0660,但我也嘗試過0777.但是,當我嘗試更新記錄時,我得到'數據庫已鎖定'錯誤。

我以前在不同的服務器上使用過相同的數據庫,但是沒有使用PDO,但使用了$db = new SQLite3('mailing.db', SQLITE3_OPEN_READWRITE); 我無法使用相同的腳本,因爲新服務器上未啓用SQLITE,但是PDO_SQLITE爲。

我的phpinfo()說:

  • PDO驅動程序的MySQL,ODBC,pgsql的,SQLite的
  • PDO_SQLITE。 PDO驅動程序的SQLite 3.x中啓用SQLite庫3.3.6
  • '--without-sqlite的'
  • '--without-sqlite3的'

當然我試圖使新服務器上的SQLite首先,我可以使用原始腳本。但是因爲我不是系統工程師(只是一名開發人員;))我曾希望我可以使用PDO選項。

我的問題與我的PHP配置有關,還是我的腳本錯了?

+0

在每次查詢之後,我們通常在首次返回結果後關閉與數據庫的連接。這會清理所有內容並確保SQLite已準備好進行下一個查詢。如果您希望我可以發佈一個示例,但由於帶有錯誤檢查的try/catch語句,因此它很長。 –

+0

感謝@JayBlanchard的快速回復。你的意思是我應該在$ db-> query之後關閉$ db,並在執行更新之前再次打開並在執行更新之後再次關閉它。這不是一個巨大的開銷嗎? –

+0

開銷並不像您想象的那麼大,您可能只想重新考慮您的代碼組織。我們創建一個包含'try/catch'的函數,包括連接和關閉。我們發送所有查詢到相同的功能,並處理所有事情。 –

回答

2

下面是處理查詢單程縮短版,使連接在每次運行查詢時關閉,騰出SQLite,讓下一個查詢:

define("DBC", "sqlite:database_name.db"); 

/* 
* dataQuery($query) - one argument (required), a query string 
* generic query function where the query must be specified in source where data is required e.g, 
* 
*  $getFoo = "SELECT `foo` FROM `bar` ORDER BY `glorp`"; 
*  $results = dataQuery($getFoo); 
* 
* All functions forming a query utilize this single function to return the results of their queries. The database 
* connection is instantiated and then destroyed (when the script completes) within this function. 
*/ 

function dataQuery($query) 
{ 
    // establish database connection 
    try 
    { 
     $db = new PDO(DBC); 
     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    } 
    catch(PDOException $e) 
    { 
     $errorMsg = $e->getMessage(); 
     return $errorMsg; 
    } 

    // try to run query 
    try 
    { 
     $queryResults = $db->query($query); 
     if($queryResults != null) 
     { 
      $results = $queryResults->fetchAll(PDO::FETCH_OBJ); // return an object, you can return an array 
      $queryResults = NULL; // closes the connection 
      return $results; 
     } 
    } 
    catch(PDOException $e) 
    { 
     $errorMsg = $e->getMessage(); 
     return $errorMsg; 
    } 
} 

已經做到了這一點,我們現在可以執行查詢 -

$query = "SELECT `foo` FROM `bar`"; 
$results = dataQuery($query); 

我們可以通過成果循環併發送一些更新數據庫或任何我們需要做的。一旦返回結果,連接就會每次被清除(它被設置爲NULL)。

最顯着的好處是連接到數據庫和從數據庫返回數據獨立於查詢本身,使代碼更加模塊化和靈活。

+1

謝謝Jay,我的劇本現在正在重新開始工作。我會接受你的回答。 –