Excluir coluna da tabela SQLite

Eu tenho um problema: eu preciso excluir uma coluna do meu database SQLite. Eu escrevi essa consulta

alter table table_name drop column column_name 

mas não funciona. Por favor me ajude.

De: http://www.sqlite.org/faq.html :

(11) Como faço para adicionar ou excluir colunas de uma tabela existente no SQLite.

O SQLite tem suporte ALTER TABLE limitado que você pode usar para adicionar uma coluna ao final de uma tabela ou para alterar o nome de uma tabela. Se você quiser fazer alterações mais complexas na estrutura de uma tabela, precisará recriar a tabela. Você pode salvar dados existentes em uma tabela temporária, descartar a tabela antiga, criar a nova tabela e, em seguida, copiar os dados de volta da tabela temporária.

Por exemplo, suponha que você tenha uma tabela chamada “t1” com os nomes das colunas “a”, “b” e “c” e que você deseja excluir a coluna “c” dessa tabela. As etapas a seguir ilustram como isso pode ser feito:

 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; 

Em vez de eliminar a tabela de backup, basta renomeá-la …

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

Para simplificar, por que não criar a tabela de backup a partir da instrução select?

 CREATE TABLE t1_backup AS SELECT a, b FROM t1; DROP TABLE t1; ALTER TABLE t1_backup RENAME TO t1; 

http://lists.osgeo.org/pipermail/grass-user/2006-January/031981.html

Há também uma ferramenta chamada Sqliteman, que oferece opção visual para descartar colunas.

Obrigado, Jignesh

=> Crie uma nova tabela diretamente com a seguinte consulta:

 CREATE TABLE Table_name (Column_1 text,Column_2 text); 

=> Agora insira os dados em table_name de Existing_table com a seguinte consulta:

 insert into Table_name (Column_1,Column_2) FROM Existing_Table; 

=> Agora, elimine a tabela existente seguindo a consulta:

 DROP Existing_Table; 

Para SQLite3 c ++:

 void GetTableColNames( tstring sTableName , std::vector *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 *pvsColsToDelete ) { UASSERT(pvsColsToDelete); execDML( StringOps::tstringTo_stdString(_T("begin transaction;")).c_str() ); std::vector 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() ); } 

Esta opção funciona somente se você puder abrir o database em um navegador de database como o DB Browser para SQLite .

No navegador do database para SQLite:

  1. Vá até a guia “Estrutura de database”
  2. Selecione sua tabela Selecione Modificar tabela (logo abaixo das guias)
  3. Selecione a coluna que você deseja excluir
  4. Clique no campo Remover e clique em OK

No caso de alguém precisar de uma function PHP (quase) pronta para uso, o seguinte é baseado nesta resposta :

 /** * 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`;"); } 

Em contraste com outras respostas, o SQL usado nessa abordagem parece preservar os tipos de dados das colunas, enquanto algo como a resposta aceita parece resultar em todas as colunas do tipo TEXT .

Atualização 1:

O SQL usado tem a desvantagem de as colunas de autoincrement não serem preservadas.