it-swarm.com.de

Spalte aus der SQLite-Tabelle löschen

Ich habe ein Problem: Ich muss eine Spalte aus meiner SQLite-Datenbank löschen. Ich habe diese Anfrage geschrieben

alter table table_name drop column column_name 

aber es funktioniert nicht. Bitte hilf mir.

92
sandy

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

(11) Wie kann ich in SQLite Spalten aus einer vorhandenen Tabelle hinzufügen oder löschen?.

SQLite hat eine eingeschränkte ALTER TABLE-Unterstützung, mit der Sie eine .__ hinzufügen können. Spalte bis zum Ende einer Tabelle oder um den Namen einer Tabelle zu ändern. Wenn du Wenn Sie komplexere Änderungen in der Struktur einer Tabelle vornehmen möchten, können Sie muss die Tabelle neu erstellen. Sie können vorhandene Daten in einem .__ speichern. temporäre Tabelle, löschen Sie die alte Tabelle, erstellen Sie die neue Tabelle, und kopieren Sie dann die Daten aus der temporären Tabelle zurück.

Angenommen, Sie haben eine Tabelle mit dem Namen "t1" mit den Spaltennamen "a", "b" und "c" und dass Sie die Spalte "c" daraus löschen möchten Tabelle. Die folgenden Schritte veranschaulichen, wie dies getan werden kann:

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;
170
MeBigFatGuy

Anstatt die Sicherungstabelle zu löschen, benennen Sie sie einfach um ...

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;
51
Duda

Der Einfachheit halber sollten Sie die Sicherungstabelle nicht mit der select-Anweisung erstellen.

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

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

Es gibt auch ein Werkzeug namens Sqliteman , das eine visuelle Option zum Löschen von Spalten bietet.

Danke, Jignesh

7
Jignesh Gohel

=> Erstellen Sie eine neue Tabelle direkt mit der folgenden Abfrage:

CREATE TABLE Table_name (Column_1 text,Column_2 text);

=> Fügen Sie nun die Daten in Tabellenname aus der vorhandenen Tabelle mit der folgenden Abfrage ein:

insert into Table_name (Column_1,Column_2) FROM Existing_Table;

=> Nun lösche die Existing_table mit folgender Abfrage:

DROP Existing_Table;
3
user3317939

Diese Option funktioniert nur, wenn Sie den DB in einem DB-Browser wie DB Browser for SQLite öffnen können.

Im DB Browser für SQLite:

  1. Gehen Sie zur Registerkarte "Datenbankstruktur". 
  2. Wählen Sie Ihre Tabelle aus Wählen Sie Tabelle ändern (direkt unter den Registerkarten)
  3. Wählen Sie die Spalte aus, die Sie löschen möchten
  4. Klicken Sie auf das Feld Entfernen und klicken Sie auf OK
3
MagTun

Für 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() );   
}
1
Sunny127

Falls jemand eine (fast) einsatzbereite PHP - Funktion benötigt, ist basierend auf dieser Antwort :

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

Im Gegensatz zu anderen Antworten scheint die in diesem Ansatz verwendete SQL die Datentypen der Spalten beizubehalten, während etwa die akzeptierte Antwort dazu führt, dass alle Spalten den Typ TEXT haben.

Update 1:

Die verwendete SQL hat den Nachteil, dass autoincrement Spalten nicht beibehalten werden.

0
Uwe Keim