AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Automatiach erstellte Syntax

Automatiach erstellte Syntax

Ein Thema von Delbor · begonnen am 5. Sep 2017 · letzter Beitrag vom 9. Sep 2017
Antwort Antwort
Seite 1 von 5  1 23     Letzte » 
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#1

Automatiach erstellte Syntax

  Alt 5. Sep 2017, 21:47
Datenbank: SQLite • Version: 253.1.0.102 • Zugriff über: FireDac
Hi zusammen

In meinem Testprogrämmchen hab ich in den letzten Tagen endlich mal auch das getestet, wofür es gedacht war: SQLite und das erstellen einer einfachen Datenbank:
Delphi-Quellcode:
procedure TDMLSQLite.CreateAndConnectDB(Sender: TObject);
  var SQLSring: String;
begin
  try
    DMLSQLite.FDSQLiteConnection.Connected := false;
    DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='F:\SQLiteDatabases\'+ 'DVZO.db';
    DMLSQLite.FDSQLiteConnection.Params.Values['FailIfMissing']:='False';
    DMLSQLite.FDSQLiteConnection.Connected := true;
    SQLSring:='CREATE TABLE Bildtabelle (BildID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, Bildname VARCHAR(50), Bitmap BLOB, NEF BLOB);';
    DMLSQLite.FDSQLiteConnection.ExecSQL(SQLSring);
  except
    on E: EDatabaseError do
     ShowMessage('Exception raised with message' + E.Message);
  end;
end;
Das obige Codeeschnipsel richtet sich nach Beiträgem aus diesem Forum und tut genau das, was es soll. Mit einer passenden Extension versehen (*.sqlite statt *.db) konnte ich sie auch in einer Freeware-SQLite-DB aus dem Netz öffnen. Soweit so gut. Aber nun stellte sich mir die Frage, meine MySQL-Bilderdatenbank auf SQLite umzubauen - also hab ich noch was in Google gesucht. Und fand da prompt ein offenbar in Python geschriebenes Plug-In für MySQL Workbench.
Damit konnte ich das MySQL-Script der DB nach SQLite portieren.Ein Schnipsel aus dem resultierenden SQLite-Script:
Delphi-Quellcode:
PRAGMA foreign_keys = ON

-- Schema: ContentMasterData
ATTACH "ContentMasterData.sdb" AS "ContentMasterData";
BEGIN;
CREATE TABLE "ContentMasterData"."bildtabelle"(
                                "idBild" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("idBild">=0),
                                "Thumbnail" BLOB,"Bitmap" BLOB,
                                "Jpeg" BLOB,
                                "FolderId" VARCHAR(32));

CREATE TABLE "ContentMasterData"."galerietabelle"(
                                "Gallery_ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("Gallery_ID">=0),
                                "GalleryName" VARCHAR(50));

CREATE TABLE "ContentMasterData"."CSS-Tabelle"(
                                "idCSS" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("idCSS">=0),
                                "PageCSS" LONGTEXT NOT NULL,"MenueCSS" LONGTEXT NOT NULL);
Grundsätzlich auch das kein grosses Problem - ich denke, ich packe die einzelnen Createtable-Konstrukte in jeweils eine Funktion und packe sie dann folgendermassen in meine DB-Createprozedur:
Delphi-Quellcode:
SQLSring:= Funktion1;
SQLSring:= Funktion2;
Eine offene Fage bleibt aber doch: wie gehe ich in Delphi mit den ersten Zeilen um? Wobei Zeile 1 offenbar ein Kommentar ist und somit wegfällt:

Delphi-Quellcode:
PRAGMA foreign_keys = ON

-- Schema: ContentMasterData
ATTACH "ContentMasterData.sdb" AS "ContentMasterData";
BEGIN;
Das BEGIN in derletzten Zeile stammt von MySQL Workbench; am Schluss des Dokuments steht ein Commit, das ich als das Gegenstück zu BEGIN interptiere, also eigentlich einem end; in Delphi entspricht. Beide können also einfach weg.
Was aber mache ich mit ATTACH und "PRAGMA foreign_keys = ON"? Das "ON" war übrigens original ein "OFF" und wurde von mir geändert.

ATTACH dient offenbar zu Abfragen mehrere DB's, und deshalb denke ich, kann es ebenfalls weg.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.288 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Automatiach erstellte Syntax

  Alt 5. Sep 2017, 22:55
ATTACH dient offenbar zu Abfragen mehrere DB's, und deshalb denke ich, kann es ebenfalls weg.
Die Doku hilft...
https://www.sqlite.org/lang_attach.html
Zitat:
The ATTACH DATABASE statement adds another database file to the current database connection.
...
Tables in an attached database can be referred to using the syntax schema-name.table-name.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#3

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 06:02
pragma foreign keys off
dient wahrscheinlich dem "entspannten" Import von Daten ohne fortwährende Berücksichtigung der foreign keys.
Bedeutet, die Import Reihenfolge von Tabellen und enthaltenen Records ist (erstmal) egal, muss und wird nicht geprüft, ist schneller, erzeugt keine Foreign Key violations bei unpassenden Daten, Script läuft also durch.
Am Ende sollte dann ein "on" stehen, womit die Prüfung aktiviert wird.

Attach wurde schon genannt. Macht bei einer einzigen DB oder besser (original) Schema auch kein Sinn. Das Konvertierungswerkzeug dient aber offenbar auch dem Fall, dass mehrere mySQL Datenbanken / Schema konvertiert werden.
Attach ist dann die einzige Möglichkeit, Tabellennamen sauber zu unterscheiden, also mögliche Namenskonflikte zu vermeiden, indem es unterschiedliche Namen/Schema für die verschiedenen Ursprungsschema angibt.

Begin End oder Begin Commit macht aus dem ganzen eine Transaktion.
Wenn Du beabsichtigst, einzelne Schritte in (Delphi) Funktionen zu zerlegen, macht es vielleicht nur bedingt Sinn.
Meine Strategie wäre eher Alles oder Nichts, also Ausstieg bei Fehler und alle Änderungen verschwinden automatisch.
Bei einer Initalen DB Erzeugung käme das dem Wegwerfen der sqLite Datei gleich. Wäre auch okay.

Spätestens, wenn Du einen Stand (mit Daten) in SQLite hast, der für einen Software-Versionswechsel eine Änderung/Erweiterung des Datenmodells benötigt, ist Begin/End für alle Änderungen inkl. neuer (Stamm-)Daten vermutlich eher das, was man will.
Deine Delphi-Funktionen würden also eher nicht einzelne Tabellen anlegen, sondern eine Funktion spielt ein komplettes Änderungsskript ein.
Im Fehlerfall wird alles(!) auf den alten Stand zurückgesetzt > Rollback statt Commit.
Gruß, Jo
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 08:42
Hi zusammen

@jaenicke
Zitat:
The ATTACH DATABASE statement adds another database file to the current database connection.
Sag ich doch...

Was also macht dieses ATACH an dieser Stelle? Ist das hier gedacht, um die originale MySQL-DB und die eportierte SQLite-DB in einer Verbindung zu öffnen?
Da ich das nicht beabsichtige, brauche ichs auch nicht.

@jobo:
Zitat:
pragma foreign keys off
dient wahrscheinlich dem "entspannten" Import von Daten ohne fortwährende Berücksichtigung der foreign keys.
Nein. Ein mit Google Translation übersetztes Schnipsel aus den FAQs:
Zitat:
(22) Unterstützt SQLite Fremdschlüssel?

Ab Version 3.6.19 (2009-10-14) unterstützt SQLite Fremdschlüssel-Einschränkungen. Die Durchsetzung von Fremdschlüssel-Einschränkungen wird standardmäßig deaktiviert (für Rückwärtskompatibilität). Um die Fremdschlüssel-Zwangsvollstreckung zu aktivieren, führen Sie PRAGMA foreign_keys = ON aus oder kompilieren mit -DSQLITE_DEFAULT_FOREIGN_KEYS = 1.
Zitat:
Begin End oder Begin Commit macht aus dem ganzen eine Transaktion.
Also MySQL-intern?
Zitat:
Wenn Du beabsichtigst, einzelne Schritte in (Delphi) Funktionen zu zerlegen, macht es vielleicht nur bedingt Sinn.
Meine Strategie wäre eher Alles oder Nichts, also Ausstieg bei Fehler und alle Änderungen verschwinden automatisch.
Bei einer Initalen DB Erzeugung käme das dem Wegwerfen der sqLite Datei gleich. Wäre auch okay.
Die Frage ist hier wohl, wann das ExecSql ausgeführt wird. Von mir vorgesehen ist das ExecSql eigentlich erst ganz am Schluss auszuführen.
Zitat:
Grundsätzlich auch das kein grosses Problem - ich denke, ich packe die einzelnen Createtable-Konstrukte in jeweils eine Funktion und packe sie dann folgendermassen in meine DB-Createprozedur:
markieren
Delphi-Quellcode:
Delphi-Quellcode:
SQLSring:= Funktion1;
SQLSring:= Funktion2;
Diese Beispielsyntax wäre also eher:
Delphi-Quellcode:
SQLSring.Add:= Funktion1;
SQLSring.Add:= Funktion2;
Wenn ich die einzelnen Create Table-Konstrukte in jeweils eigene Funktionen packe, dient das lediglich meiner besseren Übersicht, abgesehen davon, dass die komplette SQL-Syntax in eine eigene Klasse/Unit ausgelagert werden könnte.
Zitat:
Im Fehlerfall wird alles(!) auf den alten Stand zurückgesetzt > Rollback statt Commit.
Das ist zwingend.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#5

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 09:13
@jobo:
Zitat:
pragma foreign keys off
dient wahrscheinlich dem "entspannten" Import von Daten ohne fortwährende Berücksichtigung der foreign keys.
Nein. Ein mit Google Translation übersetztes Schnipsel aus den FAQs:
Zitat:
(22) Unterstützt SQLite Fremdschlüssel?

Ab Version 3.6.19 (2009-10-14) unterstützt SQLite Fremdschlüssel-Einschränkungen. Die Durchsetzung von Fremdschlüssel-Einschränkungen wird standardmäßig deaktiviert (für Rückwärtskompatibilität). Um die Fremdschlüssel-Zwangsvollstreckung zu aktivieren, führen Sie PRAGMA foreign_keys = ON aus oder kompilieren mit -DSQLITE_DEFAULT_FOREIGN_KEYS = 1.
Die Erklärung von Jobo entspricht genau dem engl. Text. "Zwangsvollstreckung" ist genau der Schwachpunkt jedes Übersetzungsprogrammes.

Mir ist nicht ganz klar warum Du Delphi bemühen willst, die Daten von einer DB in eine andere zu übernehmen.
Nach meinem Verständnis braucht man dafür ein Script, das einmal läuft und gut ist.
(na gut, in der Praxis gibt's da immer etwas nach zu arbeiten und es treten Fehler auf die behandelt werden müssen, aber im Prinzip ist das nach einem Mal erledigt)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 09:18
Da sind ein bisschen sehr viel "wahrscheinlich", "offenbar" und "ich glaube" unterwegs. :-/

PRAGMA foreign keys): Bei einem Import gibt es das Problem, dass uU Datensätze importiert, die eine Referenz auf einen Datensatz besitzen, der noch nicht importiert wurde. Wenn diese Referenz als foreign key abgebildet ist, gibt es einen Fehler. Wenn man aber weiß, dass alle Referenzen nach dem Import erfüllt sind, kann man diese foreign keys deaktivieren. Das kann man für einzelne foreign keys machen, einzelne Tabellen oder die ganze Datenbank (=PRGAMA foreign_key OFF). Und dreht es nach dem Import wieder auf.

ATTACH: Wenn man in einer Sitzung auf eine andere Datenbank zugreifen möchte, kann man den Datenbankkontext mit attach neu setzen. Alle nachfolgenden Befehle beziehen sich auf die neue Datenbank. Damit ist es aber NICHT möglich auf beide Datenbanken gleichzeitig zuzugreifen.

ad Commit/Rollback: Einen ganzen Import in eine(!) Transaktion zu packen ist blanker Unsinn. Man macht eine Datensicherung, importiert und im Fehlerfall wiederholt man den Import. Transaktionen sollen so klein und kurz wie möglich sein.

Es gibt in Delphi zwei Möglichkeiten, auf eine Datenbank zuzugreifen:
- ich packe alle SQL Anweisungen in ein Script und lasse das Script ausführen
- ich führe ein SQL Statement nach dem anderen aus
Beides hat so seine Vor- und Nachteile. Im zweiten Fall hast du mehr Kontrolle+kannst in Delphi noch alles Mögliche machen. Du sagst, es geht um Konvertierung, dann ist das eher etwas, das man nur 1x macht. Dann würde ich Variante 2 bevorzugen:
2 Connections öffnen - mySQL + SQLite
- satzweise lesen/konvertieren/schreiben
- Protokoll führen/ausgeben
- schließen
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#7

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 09:37
ad Commit/Rollback: Einen ganzen Import in eine(!) Transaktion zu packen ist blanker Unsinn. Man macht eine Datensicherung, importiert und im Fehlerfall wiederholt man den Import. Transaktionen sollen so klein und kurz wie möglich sein.
Ich hatte es so verstanden, daß alle DDL-Statements in einer Transaction enthalten sind.
Es wird doch niemand auf die Idee kommen Tausende von Datensätzen mit einer Transaktion zu verarbeiten?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.172 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 10:02
Nicht jedes DBMS kann DDL-Statements in Transaktionen packen, aber bei SQLite bin ich mir nicht sicher, das funktioniert da ja anders.

Siehe auch:
https://stackoverflow.com/questions/...s-in-major-sql
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 12:30
Hi zusammen
@TigerLily
Zitat:
PRAGMA foreign keys): Bei einem Import gibt es das Problem, dass uU Datensätze importiert, die eine Referenz auf einen Datensatz besitzen, der noch nicht importiert wurde. Wenn diese Referenz als foreign key abgebildet ist, gibt es einen Fehler. Wenn man aber weiß, dass alle Referenzen nach dem Import erfüllt sind, kann man diese foreign keys deaktivieren. Das kann man für einzelne foreign keys machen, einzelne Tabellen oder die ganze Datenbank (=PRGAMA foreign_key OFF). Und dreht es nach dem Import wieder auf.
Um mal 'alle Klarheiten zu beseitigen': die Datenbank, von der hier die Rede ist, ist leer, enthält also aktuell keine Daten. Diese werden von meinem Programm von Festplatte/direkt ab Scandisc in Form von Raw-Bildern eingelesen(Pathlist) und in einer bestimmten Reihenfolge in die DB geschrieben.**
Das heisst: von der zu erstellenden SQLite-DB müssen keine Daten aus MySQL übernommen werden, und deshalb ist das 'ATTACH' hier für mich erstmal nicht von Bedeutung - was aber nicht heisst, dass ATTACH grundsätzlich unwichtig für mich wäre, denn spätestens, wenns darum geht, Backups zu erstellen oder einzulesen, hat ATTACH sehr wohl Bedeutung. Dasselbe dürfte auch für die ForeignKeys gelten. Mein DB-Modell besteht gewissermassen aus 2 Zweigen, von MySQL Workbench "Layer" genannt.
Zentral ist dabei die Bildtabelle. Sie enthhält Spalten für das Rohbild, ein Thumbnail, eine Bitmap, ein Jpeg und eine FolderID.
Anschliessend wird ein Insert auf die Describetabelle gemacht und der PK der Bildtabelle als Fremdschlüssel eingefügt.
In diesem Layer gibt es noch eine Kategorientabelle, die mit der Desribetabelle über eine n:m-Beziehung verknüpft ist. Bevor überhhaupt mit einem Insert begonnen werden kann, muss diese Tabelle Daten enthalten, ansonsten bricht die Transaktion ab, da diese Tabelle den PK für den FK der Zwischentabelle liefert.
Es kann also keinen FK geben, der auf einen noch nicht vorhandenen PK verweist. Zumindest für diesen soeben beschriebenen ersten Zweig nicht.
Spannender wirds beim 2. Zweig. Dieser besteht zentral aus einer HTML-Tabelle, welche über eine Zwischentabelle mit der Bilddescribetabelle in einer n:M-Beziehung verbunden ist. Diese HTML-Tabelle wird vorerst nicht editiert; es gibt also hier keinen Insert und damit vorerst keinen mit der Bilddescribetabelle verbundenen Datensatz. Dieser wird erst zur Progammlaufzeit erstellt.

Sinn des Programmes ist es, zur Laufzeit eine (oder mehrere) HTML-Seiten zu erstellen und dieser dann per Drag&Drop bestimmte Bilder zuzuweisen. Das ist dann auch der Zeitpunkt, an dem die benötigten PK und FK erstellt und zugewiesen werden.

Zitat:
Wenn man aber weiß, dass alle Referenzen nach dem Import erfüllt sind,...
Das, fürchte ich, ist nur dann gefahrlos, wenn die Daten aus einer DB mit gleicher Struktur stammen, also eben etwa aus einem Backup.

**Die in meinem ersten Post gezeigte 'Satelliten"-DB soll pro Kategorie die RAW-Bilder und eine Bitmap dieser Rawdaten enthalten. Ziel ist es, diese Daten nicht in der "Mutter"-DB vorzuhalten, sondern extern auf beliebigen Laufwerken. Der Grund: die RAW-Bilder sind je nach Kamera zwischen 10 und 24 Megabyte gross, die entsprechenden Bitmaps in der Originalgrösse dreimal grösser.


Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.534 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Automatiach erstellte Syntax

  Alt 6. Sep 2017, 13:13
Es kann also keinen FK geben, der auf einen noch nicht vorhandenen PK verweist.
Dann versuch doch einmal, eine Tabelle mit einem FK anzulegen, wenn es die darin referenzierte Tabelle noch gar nicht gibt, weil sie in der Erstellungsreihenfolge erst später kommt.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz