【问题标题】:Can not get data from the newly created columns in SQLite无法从 SQLite 中新创建的列中获取数据
【发布时间】:2011-09-10 01:43:40
【问题描述】:

countProductSelect 和 countProductInput 列的当前值 - INTEGER NOT NULL;

需要将INTEGER DEFAULT NULL;

PHP 代码如下。

问题在于,当尝试从时间列和 countProductSelectTmp countProductInputTmp 更新数据和 countProductSelect countProductInput 时,出现错误 - “no such column: countProductSelectTmp”。

如何处理这个错误?或者也许有更多受过教育的算法来解决原始问题?

/**
 * Updating the database
 * 
 * @return bool
 */
protected function _updateDB()
{
    $version = '3.8.4.0';

    $this->_pdo->exec('
        ALTER TABLE data ADD optionalCountProduct INTEGER DEFAULT NULL;
        ALTER TABLE data ADD countProductSelectTmp INTEGER DEFAULT NULL;
        ALTER TABLE data ADD countProductInputTmp INTEGER DEFAULT NULL;
        UPDATE data SET countProductSelectTmp = countProductSelect, countProductInputTmp = countProductInput;
    ');

    $this->_deleteSQLiteColumn(array('countProductSelect', 'countProductInput'));

    // BUG
    // countProductSelect and countProductInput can not get the value countProductSelectTmp and countProductInputTmp
    $this->_pdo->exec('
        ALTER TABLE data ADD countProductSelect INTEGER DEFAULT NULL;
        ALTER TABLE data ADD countProductInput INTEGER DEFAULT NULL;
        UPDATE data SET countProductSelect = countProductSelectTmp, countProductInput = countProductInputTmp;
        UPDATE version SET id = "' . $version . '";
    ');

    $this->_deleteSQLiteColumn(array('countProductSelectTmp', 'countProductInputTmp'));

    return true;
}


/**
 * Remove column from a SQLite Table
 * 
 * @param array $column name of the column to remove
 * @return bool
 */
protected function _deleteSQLiteColumn(array $column)
{
    return (bool)$this->_pdo->exec('
        BEGIN TRANSACTION;
        CREATE TEMPORARY TABLE backup(' . $this->_getFullColumnsString() . ');
        INSERT INTO backup SELECT ' . $this->_getShortColumnsString() . ' FROM data;
        DROP TABLE data;
        CREATE TABLE data(' . $this->_getFullColumnsString($column) . ');
        INSERT INTO data SELECT ' . $this->_getShortColumnsString($column) . ' FROM backup;
        DROP TABLE backup;
        COMMIT;
    ');
}

【问题讨论】:

    标签: php sqlite pdo


    【解决方案1】:

    来自fine manual

    PDO::exec — 执行一条 SQL 语句并返回受影响的行数

    但是您试图一次执行多个语句,所以它可能只执行最后一个语句。尝试按预期使用exec 并一次执行一个语句:

    $this->_pdo->exec('ALTER TABLE data ADD optionalCountProduct INTEGER DEFAULT NULL');
    $this->_pdo->exec('ALTER TABLE data ADD countProductSelectTmp INTEGER DEFAULT NULL');
    $this->_pdo->exec('ALTER TABLE data ADD countProductInputTmp INTEGER DEFAULT NULL');
    $this->_pdo->exec('UPDATE data SET countProductSelectTmp = countProductSelect, countProductInputTmp = countProductInput');
    

    然后再用你的下一个多语句exec 和你的_deleteSQLiteColumn

    就更好的方法而言,看起来您想要做的只是删除NOT NULL 约束,但SQLite's ALTER TABLE 有点受限,因此您的“添加列、复制列、通过表复制删除列”方法是你能做的最好的;来自SQLite FAQ

    例如,假设您有一个名为“t1”的表,其中列名称为“a”、“b”和“c”,并且您想从该表中删除“c”列。以下步骤说明了如何做到这一点:

    BEGIN TRANSACTION;
    CREATE TEMPORARY TABLE t1_backup(a,b);
    INSERT INTO t1_backup SELECT a,b FROM t1;
    DROP TABLE t1;
    CREATE TABLE t1(a,b);
    INSERT INTO t1 SELECT a,b FROM t1_backup;
    DROP TABLE t1_backup;
    COMMIT;
    

    【讨论】:

    • 问题依然存在。仍然需要帮助。
    • @Gemorroj:你的新版本是什么样的?我早上回来看看。
    猜你喜欢
    • 2018-05-28
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多