2010-10-22 11 views
8

Ich muss eine DROP COLUMN-Routine zum Manipulieren von SQLite-Datenbanken schreiben.SQLite Dropspaltenroutine

Es wäre so etwas wie folgt aufgerufen werden:

dropColumn("SomeTable", "SomeColumn"); 

Die SQLite FAQ sagt, dass eine Spalte fallen zu lassen, haben Sie eine temporäre Tabelle zu erstellen, die Spalten enthält, die Sie wollen, und dann die Daten kopieren über zu und dann umbenennen.

Es sollte nicht zu schwer sein, das in eine Routine einzukapseln. Aber es sieht so aus, als wäre es nervig, es zu schreiben.

Sicher hat jemand da draußen schon eine solche Routine geschrieben. Wenn ja, kann ich es bitte stehlen? :)

+0

Es ist im Grunde davon abhängig, welche Plattform Sie SQLite einsetzen wird auf. Es sei denn, Sie möchten SQlite mit der internen Routine neu kompilieren? – MPelletier

+0

@MPelletier, die Plattform ist .Net. Aber ich denke, der Code sollte leicht auf jede andere moderne Plattform portierbar sein. Es sollte nur einige SQL ausführen und einige String-Manipulation durchführen. –

+0

in diesem Fall, ja. Eine Sache, die verwendet werden kann, um die Tabelle leicht neu zu erstellen, ohne die ursprüngliche 'Create Table' zu ​​analysieren, ist' PRAGMA table_info'. – MPelletier

Antwort

5

Hier einige Pseudo-Code für Sie:

columnNameList = "" 
newTableStr = "CREATE TABLE tempMyTable (" 
execute statement: "PRAGMA table_info('MyTable')" 
While looping through RecordSet 
    If RecordSet.name != tableRowToDeleteName 
    If columnNameList != "" Then columnNameList += "," 
    columnNameList += RecordSet.name 

    newTableStr += RecordSet.name + " " + RecordSet.type 
    If RecordSet.notnull Then 
     newTableStr += " NOT NULL" 
    End If 
    If RecordSet.dflt_value != "" Then 
     newTableStr += " DEFAULT(" + RecordSet.dflt_value + ")" 
    End If 
    If Not Last Record in RecordSet 
     newTableStr += "," 
    End If 
    End If 
End Loop 
newTableStr += ");" 

execute statement: newTableStr 
execute statement: "INSERT INTO tempMyTable (" + columnNameList + ")" + 
        "SELECT " + columnNameList + " FROM MyTable;" 

Delete table: MyTable 
Rename Table: tempMyTable to MyTable 
+1

Vergessen Sie nicht die Indizes und Trigger auf dem Tisch! "DROP TABLE" löscht auch die teilnehmenden Indizes, Trigger und Fremdschlüssel. Sie können 'SELECT * FROM sqlite_master WHERE type! = 'Table' UND tbl_name = 'MyTable')' verwenden, um die CREATE-Anweisungen für sie zu erhalten. Natürlich, wenn der Auslöser oder Index den gelöschten Schlüssel verwendet, sind Sie in Schwierigkeiten ... – Martijn

+0

@Martijn Danke für die Hinweise. Ich habe dieses Beispiel oben auf meinem Kopf geschrieben, damit es nicht vollständig ist und auch nicht beabsichtigt war. Hoffentlich hat es aber den Punkt überstanden. – Sparafusile

+0

@Sparausile: mein Kommentar war nicht als Kritik gedacht, sondern als zusätzliche Information. Tut mir leid, wenn das nicht klar war. :-) – Martijn