2015-10-03 2 views
3

При вставке нескольких строк в SQLite3 в PHP с помощью подготовленного оператора, если вы не привязываете параметр для строки, тогда значение из предыдущей строки будет быть вставлен, даже если вы «очистите» утверждение между строками.Устранение привязок в выражении SQLite3 не работает (PHP)

Посмотрите на следующий пример:

$db = new SQLite3('dogsDb.sqlite'); 

//create the database 
$db->exec("CREATE TABLE Dogs (Id INTEGER PRIMARY KEY, Breed TEXT, Name TEXT, Age INTEGER)");  

$sth = $db->prepare("INSERT INTO Dogs (Breed, Name, Age) VALUES (:breed,:name,:age)"); 

$sth->bindValue(':breed', 'canis', SQLITE3_TEXT); 
$sth->bindValue(':name', 'jack', SQLITE3_TEXT); 
$sth->bindValue(':age', 7, SQLITE3_INTEGER); 
$sth->execute(); 

$sth->clear(); //this is supposed to clear bindings! 
$sth->reset(); 

$sth->bindValue(':breed', 'russel', SQLITE3_TEXT);   
$sth->bindValue(':age', 3, SQLITE3_INTEGER); 
$sth->execute(); 

Хотя я бы ожидать вторую линию, чтобы иметь значение NULL для столбца «имя», значение «джек» вместо этого!

Таким образом, либо «очистить» не работает (хотя он возвращает true), либо я не совсем понял, что он должен делать.

Как я могу удалить привязки между вставками в SQLite3 (или даже PDO)? Каков наилучший способ вставки нескольких строк, где некоторые строки могут иметь нулевые значения для некоторых полей?

+0

Это только что подтвердил, как PHP ошибка, смотрите здесь: [https://bugs.php.net/bug.php?id=70628](https://bugs.php.net/bug. php? id = 70628) – symos

ответ

0
#include <sqlite3.h> 
#include <stdio.h> 

int main(void) { 

    sqlite3 *db; 
    char *err_msg = 0; 
    sqlite3_stmt *res; 
    sqlite3_stmt *res1; 
    int rc = sqlite3_open("test.sqlite", &db); 

    if (rc != SQLITE_OK) { 

     fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); 
     sqlite3_close(db); 

     return 1; 
    } 

    char *sql = "CREATE TABLE Dogs (Id INTEGER PRIMARY KEY, Breed TEXT, Name TEXT, Age TEXT)"; 
    rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); 
    if (rc == SQLITE_OK) { 
     rc = sqlite3_step(res); 

    } 
    sqlite3_finalize(res); 

    char *sql1 = "INSERT INTO Dogs (Breed, Name, Age) VALUES (:breed,:name,:age);"; 

    rc = sqlite3_prepare_v2(db, sql1, -1, &res1, 0); 


    if (rc == SQLITE_OK) { 
     printf("%d\n", sqlite3_bind_text(res1, 1, "breed1", 6, SQLITE_STATIC)); 
     sqlite3_bind_text(res1, 2, "name1", 5, SQLITE_STATIC); 
     sqlite3_bind_text(res1, 3, "age1", 4, SQLITE_STATIC); 
     printf("%d\n", sqlite3_step(res1)); 
    } else { 

     fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db)); 
    } 
    sqlite3_reset(res1); 
    sqlite3_clear_bindings(res1); 
    printf("%d\n", sqlite3_bind_text(res1, 2, "name2", 5, SQLITE_STATIC)); 
    printf("%d\n", sqlite3_bind_text(res1, 3, "age2", 4, SQLITE_STATIC)); 

    printf("%d\n", sqlite3_step(res1)); 


    sqlite3_finalize(res1); 
    sqlite3_close(db); 

    return 0; 
} 
+0

Я сменил свой ответ на некоторый рабочий код C. возможно, вы столкнулись с ошибкой php. – user993553

+0

эта ошибка, похоже, соответствует проблеме https://bugs.php.net/bug.php?id=47145 – user993553

+0

Спасибо за ваш ответ. Если эквивалентный код работает в C, то это означает, что _probably_ это ошибка PHP. Однако я не уверен, что это связано с другой ошибкой, с которой вы связаны. – symos