使用PDO创建表时,“基表或视图已存在”

问题描述:

尝试使用PDO时CREATE TABLE时出现相当直接的错误。下面的相同查询在使用标准mysqli函数发布时工作正常。使用PDO创建表时,“基表或视图已存在”

请忽略编码风格问题,这是我遇到的问题的一个粗略工作示例。 此示例的任何部分都不应用于生产环境。

$debug  = true; 
$ftime  = date("Ymd_His_a"); 
$table   = 'tbl_' . $ftime; 
$logfile  = 'debug_logfile.txt'; 

$db    = 'somedb'; 
$driver  = "mysqli"; 
$dbhost  = "localhost"; 
$dbuser  = "someuser"; 
$dbpass  = "somepassword"; 

$logentry = "Initializing log file at line " . __LINE__ . '. Time: ' . $ftime . "\n"; 
file_put_contents($logfile, $logentry, FILE_APPEND | LOCK_EX); 



// establish PDO connection 
try{ 

    $dbx_pdo = new PDO("mysql:dbname=$db;host=$dbhost", $dbuser, $dbpass); 
    $dbx_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $dbx_pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

    // write log line 
    $logentry = "PDO CREATED $_SERVER[PHP_SELF] from line " . __LINE__ . '. Time: ' . $ftime . "\n"; 
    file_put_contents($logfile, $logentry, FILE_APPEND | LOCK_EX); 

} catch(PDOException $ex) { 
    die(json_encode(array('outcome' => false, 'message' => 'Unable to connect'))); 
    exit; 
} 



///////////////////////////////////////////////// 
// 
// CREATE TABLE 

// first, if the table happens to exist already- drop it. 
try 
{ 
    $q = "DROP TABLE IF EXISTS $table"; 
    if ($debug) { 
     echo "<pre>$q</pre> at line " . __LINE__; 
     $logentry = "$_SERVER[PHP_SELF] from line " . __LINE__ . '. Time: ' . $ftime . '. QUERY: ' . $q . "\n"; 
     file_put_contents($logfile, $logentry, FILE_APPEND | LOCK_EX); 
    } 
    $stmt = $dbx_pdo->query($q); 
    $stmt->execute(); 
    $stmt->closeCursor(); 
} catch(PDOException $err) { 
    echo "<p>$q<br>ERROR: " . $err->getMessage(); 
    exit; 
} 


// now try to create the table 
try 
{ 
    $q = " 
     CREATE TABLE $table 
     (
      `id` INT(10) NULL , 
      `code` VARCHAR(20) NULL , 
      `description` VARCHAR(12) NULL 
     ) 
     ENGINE = MYISAM; 
    "; 
    if ($debug) { 
     echo "<pre>$q</pre> at line " . __LINE__; 
     $logentry = "$_SERVER[PHP_SELF] from line " . __LINE__ . '. Time: ' . $ftime . '. QUERY: ' . $q . "\n"; 
     file_put_contents($logfile, $logentry, FILE_APPEND | LOCK_EX); 
    } 

    $stmt = $dbx_pdo->query($q); 
    $stmt->execute(); 
    $stmt->closeCursor(); 

} catch(PDOException $err) { 

    $logentry = "Error near line " . __LINE__ . '. Time: ' . $ftime . '. ERROR: ' . $err->getMessage() . "\n"; 
    file_put_contents($logfile, $logentry, FILE_APPEND | LOCK_EX); 

    echo "<p>$q<br>ERROR: " . $err->getMessage(); 
} 

// 
// CREATE TABLE 
///////////////////////////////////////////////// 

以前运行脚本,我保证logfile.txt不存在。

脚本运行之后,日志文件logfile.txt包含以下内容:

Initializing log file at line 10. Time: 20150120_135803_pm 
PDO CREATED /program/_test2.php from line 27. Time: 20150120_135803_pm 
/program/_test2.php from line 47. Time: 20150120_135803_pm. QUERY: DROP TABLE IF EXISTS tbl_20150120_135803_pm 
/program/_test2.php from line 73. Time: 20150120_135803_pm. QUERY: 
         CREATE TABLE tbl_20150120_135803_pm 
         (
           `id` INT(10) NULL , 
           `code` VARCHAR(20) NULL , 
           `description` VARCHAR(12) NULL 
         ) 
         ENGINE = MYISAM; 

Error near line 83. Time: 20150120_135803_pm. ERROR: SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'tbl_20150120_135803_pm' already exists 

脚本没有被重新加载或称为第二时间,而不是嵌入在一个框架。这是香草PHP,你看到的是你得到的。日志写入(设置为追加模式)是为了确保脚本不会以某种方式第二次重新加载。

我已经检查过,确保在运行此脚本之前,在数据库中没有任何表以tbl_开头。表不是预先存在。

后脚本运行(尽管PDO的错误消息)的表格显示了(但只有后脚本运行 - 在此之前,我已经三重检查)。

这是怎么回事?

您两次执行查询,你只需要​​当你第一次准备语句,不运行一个查询使用直接query()

$stmt = $dbx_pdo->query($q); 
$stmt->execute(); 

应该是:

$stmt = $dbx_pdo->query($q); 
+1

确认固定- 谢谢。 – 2015-01-20 19:19:09