eliminar - sqlite rename column
Eliminar columna de la tabla de SQLite (8)
=> Crea una nueva tabla directamente con la siguiente consulta:
CREATE TABLE Table_name (Column_1 text,Column_2 text);
=> Ahora inserte los datos en table_name de Existing_table con la siguiente consulta:
insert into Table_name (Column_1,Column_2) FROM Existing_Table;
=> Ahora suelte la TablaExistente siguiendo la siguiente consulta:
DROP Existing_Table;
Tengo un problema: necesito eliminar una columna de mi base de datos SQLite. Escribí esta consulta
alter table table_name drop column column_name
Pero no funciona. Por favor, ayúdame.
De: http://www.sqlite.org/faq.html :
(11) ¿Cómo agrego o elimino columnas de una tabla existente en SQLite?
SQLite tiene una compatibilidad ALTER TABLE limitada que puede usar para agregar una columna al final de una tabla o para cambiar el nombre de una tabla. Si desea realizar cambios más complejos en la estructura de una tabla, deberá volver a crear la tabla. Puede guardar los datos existentes en una tabla temporal, soltar la tabla anterior, crear la nueva tabla y luego copiar los datos de la tabla temporal.
Por ejemplo, supongamos que tiene una tabla llamada "t1" con los nombres de columnas "a", "b" y "c" y que quiere eliminar la columna "c" de esta tabla. Los siguientes pasos ilustran cómo se podría hacer esto:
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;
En caso de que alguien necesite una función de PHP (casi) lista para usar, lo siguiente se basa en esta respuesta :
/**
* 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`;");
}
A diferencia de otras respuestas, el SQL utilizado en este enfoque parece conservar los tipos de datos de las columnas, mientras que algo así como la respuesta aceptada parece dar como resultado que todas las columnas sean del tipo TEXT
.
Actualización 1:
El SQL utilizado tiene el inconveniente de que autoincrement
columnas de autoincrement
no se conservan.
En lugar de descartar la tabla de respaldo, simplemente renómbrela ...
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;
Esta opción solo funciona si puede abrir la base de datos en un navegador DB como el navegador DB para SQLite .
En el navegador DB para SQLite:
- Vaya a la pestaña, "Estructura de la base de datos"
- Seleccione su tabla Seleccione Modificar tabla (justo debajo de las pestañas)
- Seleccione la columna que desea eliminar
- Haga clic en Eliminar campo y haga clic en Aceptar
Para 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() );
}
Para simplificar, ¿por qué no crear la tabla de respaldo desde la declaración de selección?
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
También hay una herramienta llamada Sqliteman que proporciona una opción visual para colocar columnas.
Gracias, Jignesh