Wie kann ich es sicherstellen, dass Datenbankänderungen in meiner Entwicklung bei Testern und Kunden auch automatisch geupdatet werden?
Also bspw. Erstelle ich eine neue Tabelle, füge einer Tabelle ein Feld hinzu etc.
Wenn der Kunde eine neue Version des Programms mit der alten Datenbankversion ausführen will, wird schnell auf Fehler laufen ("Feld x ist nicht bekannt" o.ä.).
thx
Naja, das sind eigentlich 2 getrennte Probleme:
Dein Programm muß erkennen daß die Datenbank auf die es zugreift alt ist und aktualisiert werden muß
wenn die DB aktualisiert werden muß, dann muß es die Aktualisierung durchführen
Nummer 1 ist ziemlich simpel - füge eine neue Tabelle mit einer einzigen Spalte und einem einzigen Datensatz in die Datenbank ein. In dieser Tabelle speicherst Du eine Versionsnummer (am einfachsten die des Programmes).
Dein Programm liest dann bei jedem Start den Wert aus der Datenbank und vergleicht ihn z.B. mit seiner eigenen Versionsnummer.
Und wenn Du z.B. von Programmversion 2.3 zu Version 2.4 ein Feld in einer Tabelle hinzugefügt hast, und das Programm beim Start merkt daß es selbst Version 2.4 ist und auf einer DB mit Version 2.3 läuft, dann muß es dieses Feld automatisch in der Datenbank anlegen.
Das Programm muß also eine Art eingebaute Datenbankhistorie haben.
Nummer 2 wird u.U. komplizierter, je nachdem wie Deine Datenbankänderungen so aussehen.
Solange einfach nur neue leere Felder hinzugefügt werden (und die erstmal leer bleiben) ist das alles kein Problem.
Komplizierter könnte es nur werden, wenn z.B. ein neues Feld bei allen bestehenden Datensätzen auch gleich mit Daten gefüllt werden muß, die sich wiederum ergeben aus den Inhalten von mehreren anderen Feldern usw.
Oder wenn eine Tabelle gelöscht wird und deren Inhalte vorher teilweise in andere Tabellen verschoben werden müssen...
Das muß Dein Programm dann auch alles können, und das für alle möglichen Kombinationen von Programmversion und Datenbankversion.
DAS wird die meiste Arbeit verursachen.
Migrator.NET oder FluentMigrator machen Punkt 2 recht einfach.
Ich will ausschließlich leere Felder anfügen oder ganze neue Tabellen mit leeren Feldern anlegen.
Wie kann ich das bewerkstelligen? Kann ich dafür einfach SQLs auf die DB loslassen?
Ist jetzt keine ernst gemeinte Frage, oder?
Die Beiden von mir geposteten FW können sowas.
Natürlich generieren die auch nur SQL, denn eine andere Möglichkeit gibt es nicht.
Also ich speichere die entsprechenden SQL Statements in einer Datenbanktabelle, jeweils einer Versionsnumemr zugeordnet.
Gibt es in Visual Studio die Möglichkeit sich bspw. das SQL Statement von einer Erstellung einer Tabelle generieren zu lassen oder ähnliches? Denn sonst müsste ich jede DB Änderung selbst als SQL Statement definieren.
Hallo,
welche Probleme hast Du mit den von FZelle genannten Frameworks?
Hallo baer999,
Gibt es in Visual Studio die Möglichkeit sich bspw. das SQL Statement von einer Erstellung einer Tabelle generieren zu lassen oder ähnliches? Denn sonst müsste ich jede DB Änderung selbst als SQL Statement definieren.
Ja gibt es
Hab z.Z. nur keinen SQL-Server installiert, aber:
Rechtsklick auf tablelle->scripts, und da sollte es drinnen sein.
Gruß
Michael
Hallo,
ich mache das so :
Die Datenbankstruktur schreibe ich in den Sourcecode
Beim Start des Programms prüfe ich ob sich die Versionsnummer geändert hat.
Wenn ja dann gehe ich alle Felder durch und lege die an die fehlen und verlängere die die zu kurz sind (per SQL-Skript das dynamisch erzeugt wird).
Ich habe keine Versionshistorie, das wäre mir zu kompliziert, muss ja auch alles getestet werden.
"Keep it simple"
Versionshisorie mit Diff-Skript ist bei mir bei Dotnetnuke schon oft genug schief gelaufen. Das heisst dann : Datenbank-Backup zurückspielen und Skripts erneut laufen lassen. Bei meiner Applikation brauchte ich das noch nie.
Da ich das für mehrere verschiedene Datenbanken mache kann ich kein fertiges Framework nehmen. Es gibt da nämlich so einige Eigenheiten. Beispiel :
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
OK, das hört sich sehr gut an und spart erheblich Arbeit,
wie meinst du das "die Datenbankstruktur liegt im Quellcode"?
Ungefähr so :
// Tabelle Spaltenname Feldtyp (Länge)
string dbstru = @"
ad ad_nr float
ad ad_match nvarchar (20)
ad ad_anrede nvarchar (4)
ad ad_name1 nvarchar (40)
ad ad_name2 nvarchar (40)
ad ad_strasse nvarchar (40)
ad ad_hausnr nvarchar (10)
ad ad_lkz nvarchar (3)
ad ad_ort nvarchar (40)
";
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
Ok, das würde ich dann einfach in eine Tabelle packen und diese DataRow für DataRow durchgehen.
Wie prüft man komfortabel, ob eine Spalte in einer Datenbank existiert? Muss ich per Adapter eine DataTable füllen die ein Select mit * auf die DB ausführt und diese DataTable dann prüfen oder geht es einfacher? thx
Array oder Collection geht auch.
Ich mach das ungefähr so :
public bool FieldExists(string dat, string fld)
{
bool feldvorhanden = true;
string sqlstr = "";
DbConnection conn = CreateConnection();
DbCommand cmd;
try
{
conn.Open();
sqlstr = "select " + fld + " from " + dat + " where 0=1";
cmd = CreateCommand(sqlstr, conn);
int anz = cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
if (ex is SqlException) if (((SqlException)ex).Number == 207) feldvorhanden = false;
}
conn.Close();
return feldvorhanden;
}
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
Hallo Michael,
danke für den Hinweis. Ich stelle erst nach und nach auf Parameter um. Da es sich hier nicht um Benutzereingaben handelt, die bearbeitet werden kann zwar nichts passieren, aber besser wäre es schon.
Baer999 : Mein Code war nur ein Beispiel, wenn Du den verwendest bitte so ändern dass er mit Parametern arbeitet.
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
"A parameter is not allowed in this location. Ensure that the '@' sign is in a valid location or that parameters are valid at all in this SQL statement."
public bool DBFieldExist()
{
bool FieldExist = true;
DBVersionAdapter.Connection.Open();
System.Data.SqlServerCe.SqlCeCommand Cmd = new System.Data.SqlServerCe.SqlCeCommand("", DBVersionAdapter.Connection);
Cmd.CommandText = "SELECT @fld FROM DBVersion WHERE 1=0";
Cmd.Parameters.Add("@fld", "Version");
MessageBox.Show(Cmd.ExecuteScalar().ToString());
DBVersionAdapter.Connection.Close();
return true;
}
Wie kann ich das mit Parametern lösen?
Hallo Baer,
dann kann man das nicht mit Parametern lösen. Lass sie weg.
Wenn Du Benutzereingaben verarbeitest dann pass auf dass nur Zeichen enthalten sind die erlaubt sind, das sind Zahlen, Buchstaben und Unterstrich.
Nicht erlaubt u.a. : , . ' ´ ` "
In meiner Applikation kann das vorkommen beim Report-Generator, bei dem der Anwender angeben kann welche Felder abgefragt werden.
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3
Ja aber wie kann ich dann die obige Abfrage machen, ob eine Spalte in einer Tabelle überhaupt existiert?
Hallo baer999,
sql column exists 3. Treffer: SQL -> Check Column exists in table, if not, add
Es ist toll jemand zu sein, der nichts von der persönlichen Meinung Anderer hält. - frisch-live.de
Hi,
bei großen Datenbanken kann man aus Systemtabellen die Informationen auslesen.
MSSQL Server , Oracle und Firebird hab ich es selber schon gemacht. (MYSQL geht das denk ich auch)
Bei SQLite wird das wohl eher nicht funktionieren.
"frisch" hat da schon Beispiele für den MSSQL Server gepostet.
Es ist auf jeden fall der richtige Weg.
TIP: Probleme kannst du vielleicht mit den Berechtigungen in der DB bekommen. Bei "BerndFfm" und seiner Methode trift dies nicht zu.
Du wirst dich immer individuell einlesen müssen.
Das Leben ist schön!
Ja aber wie kann ich dann die obige Abfrage machen, ob eine Spalte in einer Tabelle überhaupt existiert?
Mein Programmschnipsel oben gibt einen boolschen Wert zurück :
True : Spalte existiert
False : Spalte existiert nicht
Viper : Ja, genau. Ausserdem lässt sich meine Methode einfach so erweitern, dass sie auch mit anderen Datenbanken funktioniert, z.B. MySQL, Sql Compact, PostgreSQL, Oracle ...
Grüße Bernd
Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3