2014-12-29 64 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,我的剧本现在正在重新开始工作。我会接受你的回答。 –