Удалить столбец из таблицы SQLite

У меня проблема: мне нужно удалить столбец из моей базы данных SQLite. Я написал этот запрос

alter table table_name drop column column_name 

но это не работает. Пожалуйста, помогите мне.

91 голос | спросил sandy 9 Maypm11 2011, 18:09:14

7 ответов


0

От: http://www.sqlite.org/faq.html :

  

(11) Как добавить или удалить столбцы из существующей таблицы в SQLite.

     

SQLite имеет ограниченную поддержку ALTER TABLE, которую вы можете использовать для добавления   столбец до конца таблицы или изменить имя таблицы. если ты   хотите сделать более сложные изменения в структуре таблицы, вы   придется воссоздать таблицу. Вы можете сохранить существующие данные в   временная таблица, удалите старую таблицу, создайте новую таблицу, затем скопируйте   данные обратно из временной таблицы.

     

Например, предположим, что у вас есть таблица с именем «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;
ответил MeBigFatGuy 13 Mayam11 2011, 10:03:00
0

Для простоты, почему бы не создать резервную копию таблицы из оператора select?

CREATE TABLE t1_backup AS SELECT a, b FROM t1;
DROP TABLE t1;
ALTER TABLE t1_backup RENAME TO t1;
ответил user4086833 21 +03002016-10-21T23:14:15+03:00312016bEurope/MoscowFri, 21 Oct 2016 23:14:15 +0300 2016, 23:14:15
0

http://lists.osgeo.org/pipermail/трава-пользователь /2006-январь /031981.html

Существует также инструмент под названием Sqliteman , который предоставляет визуальную опцию для удаления столбцов.

Спасибо, Jignesh

ответил Jignesh Gohel 14 J0000006Europe/Moscow 2012, 17:43:36
0

=> создайте новую таблицу напрямую с помощью следующего запроса:

CREATE TABLE Table_name (Column_1 text,Column_2 text);

=> Теперь вставьте данные в table_name из Existing_table с помощью следующего запроса:

insert into Table_name (Column_1,Column_2) FROM Existing_Table;

=> Теперь удалите существующую_таблицу по следующему запросу:

DROP Existing_Table;
ответил user3317939 17 FebruaryEurope/MoscowbMon, 17 Feb 2014 10:35:36 +0400000000amMon, 17 Feb 2014 10:35:36 +040014 2014, 10:35:36
0

Этот параметр работает, только если вы можете открыть БД в браузере БД, например, Браузер БД для SQLite .

В браузере БД для SQLite:

  1. Перейдите на вкладку "Структура базы данных"
  2. Выберите свою таблицу. Выберите Изменить таблицу (только под вкладками).
  3. Выберите столбец, который вы хотите удалить
  4. Нажмите «Удалить поле» и нажмите «ОК»
ответил MagTun 4 Jpm1000000pmThu, 04 Jan 2018 17:20:11 +030018 2018, 17:20:11
0

Для SQLite3 c ++:

void GetTableColNames( tstring sTableName , std::vector<tstring> *pvsCols )
{
    UASSERT(pvsCols);

    CppSQLite3Table table1;

    tstring sDML = StringOps::std_sprintf(_T("SELECT * FROM %s") , sTableName.c_str() );



    table1 = getTable( StringOps::tstringToUTF8string(sDML).c_str() );

    for ( int nCol = 0 ; nCol < table1.numFields() ; nCol++ )
    {
        const char* pch1 = table1.fieldName(nCol);  

        pvsCols->push_back( StringOps::UTF8charTo_tstring(pch1));
    }
}


bool ColExists( tstring sColName )
{
    bool bColExists = true;

    try
    {
        tstring sQuery = StringOps::std_sprintf(_T("SELECT %s FROM MyOriginalTable LIMIT 1;") , sColName.c_str() );

        ShowVerbalMessages(false);

        CppSQLite3Query q = execQuery( StringOps::tstringTo_stdString(sQuery).c_str() );

        ShowVerbalMessages(true);
    }
    catch (CppSQLite3Exception& e)
    {
        bColExists = false;
    }

    return bColExists;
}

void DeleteColumns( std::vector<tstring> *pvsColsToDelete )
{
    UASSERT(pvsColsToDelete);

    execDML( StringOps::tstringTo_stdString(_T("begin transaction;")).c_str() );


    std::vector<tstring> vsCols;
    GetTableColNames( _T("MyOriginalTable") , &vsCols );


    CreateFields( _T("TempTable1") , false );

    tstring sFieldNamesSeperatedByCommas;

    for ( int nCol = 0 ; nCol < vsCols.size() ; nCol++ )
    {

        tstring sColNameCurr = vsCols.at(nCol);

        bool bUseCol = true;

        for ( int nColsToDelete = 0; nColsToDelete < pvsColsToDelete->size() ; nColsToDelete++ )
        {
            if ( pvsColsToDelete->at(nColsToDelete) == sColNameCurr )
            {
                bUseCol = false;
                break;
            }
        }

        if ( bUseCol )
            sFieldNamesSeperatedByCommas+= (sColNameCurr + _T(","));

    }

    if ( sFieldNamesSeperatedByCommas.at( int(sFieldNamesSeperatedByCommas.size()) - 1) == _T(','))
        sFieldNamesSeperatedByCommas.erase( int(sFieldNamesSeperatedByCommas.size()) - 1 );

    tstring sDML;


    sDML = StringOps::std_sprintf(_T("insert into TempTable1 SELECT %s FROM MyOriginalTable;\n") , sFieldNamesSeperatedByCommas.c_str() );
    execDML( StringOps::tstringTo_stdString(sDML).c_str() );

    sDML = StringOps::std_sprintf(_T("ALTER TABLE MyOriginalTable RENAME TO MyOriginalTable_old\n") );
    execDML( StringOps::tstringTo_stdString(sDML).c_str() );

    sDML = StringOps::std_sprintf(_T("ALTER TABLE TempTable1 RENAME TO MyOriginalTable\n") );
    execDML( StringOps::tstringTo_stdString(sDML).c_str() );


    sDML = ( _T("DROP TABLE MyOriginalTable_old;") );   
    execDML( StringOps::tstringTo_stdString(sDML).c_str() );


    execDML( StringOps::tstringTo_stdString(_T("commit transaction;")).c_str() );   
}
ответил Sunny127 25 Maypm14 2014, 19:17:25
0

Если кому-то нужна (почти) готовая к использованию функция PHP, основан на этом ответе

 /**
 * Remove a column from a table.
 * 
 * @param string $tableName The table to remove the column from.
 * @param string $columnName The column to remove from the table.
 */
public function DropTableColumn($tableName, $columnName)
{
    // --
    // Determine all columns except the one to remove.

    $columnNames = array();

    $statement = $pdo->prepare("PRAGMA table_info($tableName);");
    $statement->execute(array());
    $rows = $statement->fetchAll(PDO::FETCH_OBJ);

    $hasColumn = false;

    foreach ($rows as $row)
    {
        if(strtolower($row->name) !== strtolower($columnName))
        {
            array_push($columnNames, $row->name);
        }
        else
        {
            $hasColumn = true;
        }
    }

    // Column does not exist in table, no need to do anything.
    if ( !$hasColumn ) return;

    // --
    // Actually execute the SQL.

    $columns = implode('`,`', $columnNames);

    $statement = $pdo->exec(
       "CREATE TABLE `t1_backup` AS SELECT `$columns` FROM `$tableName`;
        DROP TABLE `$tableName`;
        ALTER TABLE `t1_backup` RENAME TO `$tableName`;");
}

В отличие от других ответов, SQL, используемый в этом подходе, похоже, сохраняет типы данных столбцов, тогда как что-то вроде принятого ответа, похоже, приводит к тому, что все столбцы имеют тип TEXT

Обновление 1:

Используемый SQL имеет тот недостаток, что столбцы autoincrement не сохраняются.

ответил Uwe Keim 10 J000000Monday17 2017, 21:59:36

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132