简体   繁体   中英

PDO SQLite cannot update record: “database is locked”

I'm struggling with this all day. I've read numerous posts, tried all suggestions but nothing works.

This is my PHP code:

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;  
}

I run PHP v5.3.3. With just the loop after the select I get the correct values from the table, so I can access the database, which is in the same folder as my script. The folder has 0777 rights, the database and the script both have 0660, but I've also tried with 0777. But when I try to update a record I get the 'database is locked' error.

I've used the same database before on a different server, but not with PDO but with $db = new SQLite3('mailing.db', SQLITE3_OPEN_READWRITE); I couldn't use the same script because SQLITE isn't enabled on the new server, but PDO_SQLITE is.

My phpinfo() says:

  • PDO drivers mysql, odbc, pgsql, sqlite
  • pdo_sqlite. PDO Driver for SQLite 3.x enabled SQLite Library 3.3.6
  • '--without-sqlite'
  • '--without-sqlite3'

Of course I tried to enable SQLite on the new server first so I could use the original script. But because I'm not a system engineer (just a developer ;)) I had hoped I could use the PDO option.

Is my problem related to my PHP configuration or is my script wrong?

Here is a shortened version of one way to handle queries so that the connection is closed each time a query is run, freeing up SQLite for the next query:

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;
    }
}

Having done this we can now execute a query -

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

We could loop through the results and send several updates to the database or whatever we need to do. The connection gets cleaned up each time (where it is set to NULL) as soon as the results are returned.

The most notable benefit is that connecting to and returning data from the database is independent of the queries themselves, making the code much more modular and flexible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM