Nach einigen Wiederholungen sah unser Ansatz ungefähr so aus:
Eine Datei pro Tabelle und pro gespeicherte Prozedur. Außerdem separate Dateien für andere Dinge wie die Einrichtung von Datenbankbenutzern und das Auffüllen von Nachschlagetabellen mit ihren Daten.
Die Datei für eine Tabelle beginnt mit dem Befehl CREATE und einer Reihe von ALTER-Befehlen, die im Laufe der Entwicklung des Schemas hinzugefügt werden. Jeder dieser Befehle ist in Klammern gesetzt, um zu prüfen, ob die Tabelle oder Spalte bereits existiert. Das bedeutet, dass jedes Skript in einer aktuellen Datenbank ausgeführt werden kann und nichts verändert. Es bedeutet auch, dass das Skript jede alte Datenbank auf das neueste Schema aktualisiert. Und bei einer leeren Datenbank erstellt das CREATE-Skript die Tabelle und die ALTER-Skripte werden alle übersprungen.
Wir haben auch ein Programm (in Python geschrieben), das das Verzeichnis mit den Skripten durchsucht und sie zu einem großen Skript zusammenfügt. Es analysiert die SQL-Skripte gerade so weit, dass es Abhängigkeiten zwischen den Tabellen ableitet (auf der Grundlage von Verweisen auf Fremdschlüssel) und sie entsprechend anordnet. Das Ergebnis ist ein riesiges SQL-Skript, das die Datenbank in einem Rutsch auf Vordermann bringt. Das Programm, das die Skripte zusammenstellt, berechnet auch den MD5-Hash der Eingabedateien und verwendet diesen, um eine Versionsnummer zu aktualisieren, die in eine spezielle Tabelle im letzten Skript der Liste geschrieben wird.
Das Ergebnis ist, dass das Datenbankskript für eine bestimmte Version des Quellcodes das Schema erstellt, mit dem dieser Code interagieren soll. Es bedeutet auch, dass es ein einziges (etwas umfangreiches) SQL-Skript gibt, das dem Kunden zur Verfügung gestellt wird, um neue Datenbanken zu erstellen oder bestehende Datenbanken zu aktualisieren. (Dies war in diesem Fall wichtig, weil es viele Instanzen der Datenbank geben würde, eine für jeden ihrer Kunden).