Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Automatiach erstellte Syntax (https://www.delphipraxis.net/193754-automatiach-erstellte-syntax.html)

Delbor 5. Sep 2017 20:47

Datenbank: SQLite • Version: 253.1.0.102 • Zugriff über: FireDac

Automatiach erstellte Syntax
 
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

jaenicke 5. Sep 2017 21:55

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von Delbor (Beitrag 1380377)
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.

jobo 6. Sep 2017 05:02

AW: Automatiach erstellte Syntax
 
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.

Delbor 6. Sep 2017 07:42

AW: Automatiach erstellte Syntax
 
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

p80286 6. Sep 2017 08:13

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von Delbor (Beitrag 1380382)
@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

TigerLilly 6. Sep 2017 08:18

AW: Automatiach erstellte Syntax
 
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

p80286 6. Sep 2017 08:37

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von TigerLilly (Beitrag 1380384)
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

TigerLilly 6. Sep 2017 09:02

AW: Automatiach erstellte Syntax
 
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

Delbor 6. Sep 2017 11:30

AW: Automatiach erstellte Syntax
 
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

DeddyH 6. Sep 2017 12:13

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von Delbor (Beitrag 1380406)
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.

Delbor 6. Sep 2017 13:47

AW: Automatiach erstellte Syntax
 
Hi DeddyH
Zitat:

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.
Sorry, wieso sollte ich dies tun? Ich habe TigerLilys Aussage ja gar nicht angezweifelt:
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.
Ausserdem bestätigt meine Aussage diejenige von TigerLili(oder umgekehrt), ob das nun in MySQL oder sonstwo ist:
Zitat:

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.
Gruss
Delbor

DeddyH 6. Sep 2017 13:53

AW: Automatiach erstellte Syntax
 
Wir reden doch hier von DDL (Data Definition Language) und nicht von DML (Data Manipulation Language), oder täusche ich mich? Das bedeutet, dass alle Tabellen erst einmal erstellt werden, bevor die erste davon befüllt wird. Das bedeutet aber auch, dass man, wenn man die Fremdschlüssel sofort definiert, die Erstellungsreihenfolge der Tabellen beachten muss, da das sonst in die Hose geht.

Delbor 6. Sep 2017 15:34

AW: Automatiach erstellte Syntax
 
Hi DeddyH
Ja, wir reden erstmal von DDL:
Zitat:

Das bedeutet, dass alle Tabellen erst einmal erstellt werden, bevor die erste davon befüllt wird. Das bedeutet aber auch, dass man, wenn man die Fremdschlüssel sofort definiert, die Erstellungsreihenfolge der Tabellen beachten muss, da das sonst in die Hose geht.
In meinem Fall hat MySQL Workbench die Tabelle erstellt, nachdem ich in Workbench ein Forward-Engineering durchgeführt habe. Dabei wurden die FK-Spalten schon im Workbench-Modell definiert, nicht aber deren Werte - die ergeben sich erst beim Insert der Daten aufgrund des PK-Wertes in der vorgängig mit Daten gefüllten Tabelle.
Das DB-Modell entstand seinerzeit mit im wesentlichen deiner und ccLouds Hilfe im Delphi-Treff. Leider hab ich die Beiträge nicht mehr gefunden.
Seinerzeit haben wir, auch mit Rc2c, viel über Normalisierung und u.a. auch Dateninkonsistenz diskutiert.

Gruss
Delbor

Delbor 7. Sep 2017 11:35

AW: Automatiach erstellte Syntax
 
Liste der Anhänge anzeigen (Anzahl: 3)
Hi zusammen
Soeben hab ich mal versucht, die Datenbank zu erstellen. Als erstes hab ich mal das von MySQL-Workbench erstellten SQLite-CreateScript in Funktionen pro erstellter Tabelle aufgeteilt. Nachfolgend die Prozedure, die die DB erstellen sollte:
Delphi-Quellcode:
procedure TDMLSQLite.ContentmasterDBCreate;
  var SQLString: String;
begin
  try
    DMLSQLite.FDSQLiteConnection.Connected := false;
    DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite';// Geänderte Zeile(M statt m)
    DMLSQLite.FDSQLiteConnection.Params.Values['FailIfMissing']:='False';
    DMLSQLite.FDSQLiteConnection.Params.Values['PRAGMA foreign_keys']:='ON';
    DMLSQLite.FDSQLiteConnection.Connected := true;
    SQLString := '';
    SQLString := Createbilddescribetabelle;
    SQLString := SQLString + Createbilddescribetabelle_has_HtmlTabell;
    SQLString := SQLString + Createbildtabelle;
    SQLString := SQLString + CreateCSSTabelle;
    SQLString := SQLString + Creategalerietabelle;
    SQLString := SQLString + CreateHTMLTable;
    SQLString := SQLString + CreateJavascriptTable;
    SQLString := SQLString + Createkategorien_tabelle;
    SQLString := SQLString + Createkategorien_tabelle_has_bildDescribeTabelle;
    SQLString := SQLString + CreateMenueTabelle;
    SQLString := SQLString + CreateSubMenue2Table;
    SQLString := SQLString + CreateSubmenuetabelle;
    DMLSQLite.FDSQLiteConnection.ExecSQL(SQLString);
  except
    on E: EDatabaseError do
     ShowMessage('Exception raised with message' + E.Message);
  end;
end;
Und das ist die Fehlermeldung, die mir Delphi anzeigt:

Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: unknown database "ContentMasterData"' aufgetreten.
---------------------------
Darauf hab ich folgende Zeile geändert:
Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite';

in

Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentMasterData\ContentMasterData.sqlite';

In allen Funktionen, die dem SQLString zugewiesen werden, ist das Teilwort 'Master' gross geschrieben, also müsste dies auch im DB-Namen der von SQLite erzeugten DB der Fall sein. Trotzdem ändert sich die Fehlermeldung nicht...
Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: unknown database "ContentMasterData"' aufgetreten.
---------------------------
Im Anhang zeigt ein Jpeg die Situation im besagten Verzeichnis. Auf Doppelklick auf den da gezeigten Ordner öffnet sich sqlite-Expert und zeigt mir eben diesen Ordner an. - mit einigen DB-spezifischen Metadaten, aber ohne die Tabellen.
Was habe ich falsch gemacht?

Gruss
Delbor

TigerLilly 7. Sep 2017 11:44

AW: Automatiach erstellte Syntax
 
Sollte das statt

DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite'

nicht besser heißen:

DMLSQLite.FDSQLiteConnection.Params.Add('Database= M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite' );

nahpets 7. Sep 2017 12:20

AW: Automatiach erstellte Syntax
 
Eventuell sind aber auch einfach nur die Leerzeichen im Dateinamen das Problem, fasse den Dateinamen mal in " ein:

Delphi-Quellcode:
 DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='"M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite"';

Delbor 7. Sep 2017 12:42

AW: Automatiach erstellte Syntax
 
Hi zusammen

@TigerLilly
So, wie ich das verstanden habe, sind das zwei Mögliche Schreibweisen.

@nahpets:
Soeben ausprobiert - und scheint genau so zu sein. Jedenfalls ist jetzt die Fehlermeldung anders:
Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: unable to open database file' aufgetreten.
---------------------------
Eigentlich bin ich es von MySQL-Workbench gewohnt, wenn ich ein Forward-Engineering mache, um die entworfene DB zu erstellen, muss ich vorher einen Ordner erstellen und diesen als "Datenbank" angeben. Ist hier wohl auch nicht anders - bisher war ich nur etwas irritiert, weil eine "DB" mit verknüpfung zum sqlite-Expert angelegt wurde.

War aber Fehlanzeige - selbe Fehlermeldung...
Aktuelle Pfadangabe[13:45]:
Delphi-Quellcode:
['Database']:='"M:\SQLite-DB Corner\ContentMasterData\ContentMasterData.sqlite"';

Gruss
Delbor

TigerLilly 7. Sep 2017 13:10

AW: Automatiach erstellte Syntax
 
>So, wie ich das verstanden habe, sind das zwei Mögliche Schreibweisen.

Naja, nur, wenn es "Database" schon gibt.

Delbor 7. Sep 2017 13:21

AW: Automatiach erstellte Syntax
 
Hi zusammen

Die letzte gezeigte Fehlermeldung hatte eine Besonderheit: Das, was ich hier gepostet habe, war eine Kopie aus dem Editor, und da endete die Meldung mit einem '.
Nachdem ich die Meldung mit Fortsetzen qittiert hatte, erschien sie in einem Meldungsfenster auf meiner Programmoberfläche - aber diesmal ohne das Hochkomma am Schluss...
Nun ja, ich hab dann doch mal TigerLillys Vorschlag ausprobiert und das 'm' in 'ContentMasterData' durch ein grosses seiner Art ersetzt. So, wie es in allen meinen SQL-Strings steht.
Und jetzt ist die Fehlermeldung wieder:

Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: unknown database "ContentMasterData"' aufgetreten.
---------------------------
Ich hatte in dem Ordner einen UnterOrdner ContentMasterData angelegt. Der ist nach wie vor leer.
Stattdessen habe ich jetzt wieder einen solchen mit der Endung sqlite.
Den gelöscht und...
das Spielchen geht von vorne los....:twisted:

Gruss
Delbor

Delbor 7. Sep 2017 13:42

AW: Automatiach erstellte Syntax
 
Hi TigerLilly
Zitat:

>So, wie ich das verstanden habe, sind das zwei Mögliche Schreibweisen.

Naja, nur, wenn es "Database" schon gibt.
Das explizite leeren des Parameters vor der Zuweisung hat auch nichts gebracht.

Gruss
Delbor

jobo 7. Sep 2017 14:29

AW: Automatiach erstellte Syntax
 
Aus Deinem Delphicode geht nun derzeit nicht hervor, was du in den einzelnen Abschnitten wirklich als DML Script übergibst.
Ebenso sehe ich nicht, wo dieser Fehler geschieht (welche Zeile in Delphi).

Also weitere Vermutungen:
Wenn Du lediglich das Attach rausgeworfen hast, den Rest aber belassen wie zu Anfang aufgeführt, ist das logische Schema "ContentMasterData." aus der Create Anweisung nicht mehr bekannt.
Also entweder Attach UND Schemaschreibweise entfernen
oder
beides wie generiert belassen.
oder
Attach weglassen und Schemaschreibweise auf "main".

Betreibt man tatsächlich mehrere DB attachted, kann einem das Weglassen des Schemas offenbar ziemliche Schmerzen verursachen (laut Doku).

TigerLilly 7. Sep 2017 15:01

AW: Automatiach erstellte Syntax
 
Schau dir doch mal an, was in Params - das sollte doch eine StringList sein - wirklich drinsteht:
> DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite' ;

und zwar vor dieser Zeile:
> DMLSQLite.FDSQLiteConnection.Connected := true;

Welche Delphi Version verwendest du + sind das FireDac Komponenten?

Delbor 7. Sep 2017 15:47

AW: Automatiach erstellte Syntax
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hi jobo

Das sind die ersten Zeilen des Scripts, so wie es von Workbench exportiert wurde:

Zitat:

-- Creator: MySQL Workbench 6.3.8/ExportSQLite Plugin 0.1.0
-- Author: Roger
-- Caption: Delbor-Database-Modell
-- Project: DelborpunktCH
-- Changed: 2017-04-18 16:20
-- Created: 2012-06-16 09:09
PRAGMA foreign_keys = OFF;

-- Schema: ContentMasterData
ATTACH "ContentMasterData.sdb" AS "ContentMasterData";
BEGIN;
Davon wurden alle ausser der PRAGMA-Zeile Opfer meines 'Sauberkeitsfimmels'.
Das Script selbst findest du im Anhang.


Zitat:

Aus Deinem Delphicode geht nun derzeit nicht hervor, was du in den einzelnen Abschnitten wirklich als DML Script übergibst.
Alle CREATE TABLE-Konstrukte im Anhang werden einzeln von insgesamt 12 Funktionen zurückgeliefert. ExecSQL führt also im Endeffekt das bis auf die obigen Zeilen (und das commit am Schluss)komplette Script aus.

Zitat:

Ebenso sehe ich nicht, wo dieser Fehler geschieht (welche Zeile in Delphi).
Der Fehler tritt auf, nachdem (oder eben wenn) ExecSQL ausgeführt wird/Werden sollte.

Zitat:

Also entweder Attach UND Schemaschreibweise entfernen
oder
beides wie generiert belassen.
oder
Attach weglassen und Schemaschreibweise auf "main".
ATTACH "ContentMasterData.sdb" AS "ContentMasterData";

Verstehe ich dich richtig? Das würde also z.B. so ausehen:
Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Add(ATTACH "ContentMasterData.sdb" AS "ContentMasterData";)

oder:

Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Add(main;)
Aber vielleicht krieg ich ja doch noch den Durchblick.

TigerLillly schrieb:

Zitat:

Naja, nur, wenn es "Database" schon gibt.

Und die gibts ja auch - nämlich die, welche ich in meinem ersten Post gezeigt habe - die basiert auf der selben sqlite.dll, im selben Anwendungsverzeichnis.
Und genau deswegen muss nun mit Attach die neue DB hinzugefügt werden. Richtig?

Und zu Tigerlilly: Ich hab mir die Params inzwischen angesehen; sie sind auch im Anhang zu finden.

Ich arbeite mit DelphiXE8 unter Firedac.

Gruss
Delbor

nahpets 7. Sep 2017 15:58

AW: Automatiach erstellte Syntax
 
Da mir vollkommen schleierhaft ist, wo denn genau der Fehler nun passiert, mal folgenden Vorschlag einer veränderten Prozedure:
Delphi-Quellcode:
function TDMLSQLite.ExecuteSQL(ASQL : String) : Boolean;
begin
  try
    FDSQLiteConnection.ExecSQL(ASQL);
    Result := True;
  except
    on E: EDatabaseError do begin
      ShowMessage('Fehler beim Ausführen des Statements:' + #13#13 + ASQL + #13#13 + + E.Message);
      Result := False;
    end;
  end;
end;

function TDMLSQLite.ConnectContentmasterDB : Boolean;
begin
  try
    FDSQLiteConnection.Connected := false;
    FDSQLiteConnection.Params.Values['Database'] := 'M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite';
    FDSQLiteConnection.Params.Values['FailIfMissing'] := 'False';
    FDSQLiteConnection.Params.Values['PRAGMA foreign_keys'] := 'ON';
    FDSQLiteConnection.Connected := true;
    Result := FDSQLiteConnection.Connected;
  except
    on E: EDatabaseError do begin
      ShowMessage('Fehler beim Aufbau der Datenbankverbindung: ' + #13#13 + E.Message);
      Result := False;
    end;
  end;
end;

procedure TDMLSQLite.ContentmasterDBCreate;
begin
  if ConnectContentmasterDB then begin
    if ExecuteSQL(Createbilddescribetabelle) then
    if ExecuteSQL(Createbilddescribetabelle_has_HtmlTabell) then
    if ExecuteSQL(Createbildtabelle) then
    if ExecuteSQL(CreateCSSTabelle) then
    if ExecuteSQL(Creategalerietabelle) then
    if ExecuteSQL(CreateHTMLTable) then
    if ExecuteSQL(CreateJavascriptTable) then
    if ExecuteSQL(Createkategorien_tabelle) then
    if ExecuteSQL(Createkategorien_tabelle_has_bildDescribeTabelle) then
    if ExecuteSQL(CreateMenueTabelle) then
    if ExecuteSQL(CreateSubMenue2Table) then
    if ExecuteSQL(CreateSubmenuetabelle) then ShowMessage('Das war wohl nix!');
  end;
end;
Damit könnte dann erkennbar werden, ob der Fehler bereits bei der Herstellung der Datenbankverbindung auftritt oder erst im späteren Verlauf.
Wenn im späteren Verlauf, wird das fehlerverursachende Statement zusammen mit der Fehlermeldung ausgegeben.

Dies könnte ggfls. die Fehlerursachenforschung deutlich vereinfachen.

Und das ist nur ein Vorschlag, den man strukturell sicherlich noch deutlich verbessern könnte.

Eine noch bleibende Fehlerursache ist, dass bei FDSQLiteConnection.Params.Values davon ausgegangen wird, dass die Paramter schon vorhanden sind. Eventuell zusätzlich vorhandenen Parameter werden nicht geprüft und könnten ggfls. zu unerwünschten Nebenwirkungen führen.

Sinnvoll (und meiner Meinung nach zwingend) ist es, die Parameterliste nach dem Beenden der Verbindung zu leeren und dann die gewünschten Parameter in die Liste einzufügen.
TigerLilly hat da ja, durchaus berechtigt, schon drauf hingewiesen.

Dann schreibst Du einerseits
Delphi-Quellcode:
ATTACH "ContentMasterData.sdb" AS "ContentMasterData";

und andererseits

Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='M:\SQLite-DB Corner\ContentmasterData\ContentmasterData.sqlite';

Wo wird der Zusammenhang zwischen ContentMasterData.sdb und ContentmasterData.sqlite hergestellt?
Das ist mir nicht klar, könnte das gglfs. eine Fehlerursache sein?

Zumindest hätte ich da eher sowas erwartet:

Delphi-Quellcode:
ATTACH "ContentMasterData.sqlite" AS "ContentMasterData";

Aber da mag ich mich wohl auch irren.

TigerLilly 7. Sep 2017 16:46

AW: Automatiach erstellte Syntax
 
Ich weiß nicht recht, irgendwas geht da durcheinander.

DMLSQLite.FDSQLiteConnection.Params nimmt NUR angaben zur Verbindung zur Datenbank auf. Ein Attach hat da nichts verloren.
Im Screenshot ist eine Datenbank mit .db angegeben, im Code .sqlite. Ist das ein Typo?

Gibt es die Datenbank nicht, so wird sie angelegt. Ich glaube, das hattest du gesagt, dass das passiert.

Der Fehler tritt auf, sobald connected auf true gesetzt wird - richtig? Oder erst später, bei den SQL Statements?

Das ATTACH gehört jedenfalls zu den SQL Anweisungen.

Möchtest du die .db öffnen oder die .sqlite?
Warum öffnest du eine andere DB als du dann bearbeiten willst (=die die du mit ATTACH öffnest)?

p80286 7. Sep 2017 17:27

AW: Automatiach erstellte Syntax
 
Das was Jobo oben geschrieben hat etwas anders formuliert.

Wenn ich das richtig interpretiere,#14, dann wurde in der Datei .....Contentmaster\Contentmaster.sqlite
eine dataBase mit dem namen "main" angelegt.
Jetzt gibt es zwei Möglichkeiten:
a) nach dem Connect wird mit "main" gearbeitet, also
SQL-Code:
Create Table "main.meinetabelle" .....
oder
b)das ATTACH Statement wird ausgeführt, dann kann man auf "Contentmaster.Meinetabelle" zugreifen.
SQL-Code:
Create Table "Contentmaster.Meinetabelle" .....
Eine (SQL-)DATABASE is eine logische Struktur deren physikalische Struktur eine Datei sein kann, aber nicht sein muß. Bevor Du mit der logischen database arbeiten kannst, mußt Du ihr einen phys. Speicher zuweisen bzw. wenn Du eine Datei hast muß diese mit einem Name, der DATABASE versehen werden.

Ich hoffe, das ist einigermaßen verständlich.

Gruß
K-H

jobo 7. Sep 2017 20:19

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von p80286 (Beitrag 1380555)
Das was Jobo oben geschrieben hat etwas anders formuliert.

Genau.

Ich schätze das Problem hier ist:
Das verwendete Tool generiert ein Script, Delphi SQL Componenten arbeiten aber meist Statement basiert.
Die Vermischung (oder (unvollständige) "Säuberung") von Script Elementen ist kontraproduktiv.

Kurze Lösung, lade Dir (wenn nicht vorhanden) sqlite3.exe und rufe folgendes aus einer cmd box auf:
Code:
sqlite3 testdb < script.sql
wobei in der Notation alles in einem Verzeichnis liegen muss oder sqlite3.exe im Suchpfad stehen muss.
testdb = irgendeine nicht existierende Datei
script.sql = Dein Script wie es von deinem Konvertierungstool ausgespuckt wurde.

Wenn in dem Rest (nicht von Dir veröffentlicht) keine Fehler des Konvertierungstools stecken wird es einfach durchlaufen.
Anschließend hast Du jenachdem mindesten eine Datei mehr in dem Verzeichnis, nämlich "ContentMasterData.sdb"

Ich habe hier deine Vorgabe noch etwas erweitert. Probier es mit der Kommandozeile oben aus, dann wird Dir auch klar, was es mit Deinen Connectioneinstellung in den Delphikompos auf sich hat. Schau dann mal in die Datei 'testdb' rein, mit einem sqlite tool.
Und natürlich in die Datei ContenMasterData.sdb.


Code:
-- keine fk prüfung
PRAGMA foreign_keys = OFF;
-- ist sowieso egal ohne definierte fk

-- benutze Datei ContenMasterData.sdb und nimm den logischen Bezeichner 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);
                               
insert into ContentMasterData."bildtabelle" ("Jpeg" , "FolderId" ) values( null, '../das/ist/ein/Relativpfad/xy.jpg')    ;

-- mal ohne die Anführungszeichen
insert into ContentMasterData.galerietabelle (GalleryName ) values( 'Erste Bildreihe');  
     
-- "sonderzeichen" geht nicht ohne Anführungsstriche
insert into ContentMasterData."CSS-Tabelle" (PageCSS , MenueCSS ) values( 'some page css', 'some menu css');

-- jetzt mal ohne die Schemaangabe
create table jobotesttable (aID integer, aText varchar(50));
insert into jobotesttable values (1,'jobo');

-- dedizierter, logischer Zugriff auf default aka main Schema
insert into main.jobotesttable values (null,'main.Jobo');

end;
Wenn Du mit Delphi auf ContentMasterData verbinden willst, per DelphiCode bzw. Properties, nimmst Du das vorweg, was das Script selbst macht. Das funktioniert sicher nicht gut. Die Komponenten kenne ich nicht, deswegen kann ich Dir dazu nichts sagen.
Letztlich würde ich meinen Tipp wiederholen, hier nicht groß mit Delphi rumzuwirbeln, sondern per Command Line das Script laufen zu lassen. Notfalls per ShellAPI innerhalb Deines Programms.

Achso und nochmal anders formuliert.
Wenn Du attach weglässt, dann lasse auch die vorgeschaltete Schemabezeichnung in den restlichen Scriptanweisungen weg.
Zum Spaß kannst Du ja auch noch mal Dein Konvertierungstool anwerfen und 2 Datenbanken scripten lassen. Im Ergebnis wird dann vielleicht auch klarer, was das Teil mit dem attach macht.

jobo 7. Sep 2017 20:35

AW: Automatiach erstellte Syntax
 
Und irgendwo stand noch, dass man die Daten nicht mit Transkationen lädt.

Ich würde sagen, natürlich macht man das. Dafür sind sie da.
sqlite schwächelt da leider und verhält sich nicht so, wie das m.E. sein soll.
Ist aber ein anderes Thema. Kann man ja bei Bedarf separat klären.

Delbor 8. Sep 2017 10:26

AW: Automatiach erstellte Syntax
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen

Nach längerm Suchen (inklusive überlesen...) hab ich da was interessantes gefunden:
Zitat:

Verwenden von mehreren SQLite-Datenbanken in einer Delphi-Anwendung

SQLite ermöglicht die Verwendung mehrerer Datenbanken in einer einzelnen Verbindung. Eine im Parameter Database angegebene DB ist die Hauptdatenbank. Um weitere Datenbanken hinzuzufügen, muss in der Delphi-Anwendung die ATTACH-Anweisung verwendet werden. Zum Beispiel:

Delphi-Quellcode:
 FDConnection1.ExecSQL('ATTACH ''c:\hr.sdb'' AS hr');
 FDConnection1.ExecSQL('ATTACH ''c:\cust.sdb'' AS cust');
 FDQuery1.Open('select * from "Orders" o ' +
   'left join hr."Employees" e on o.EmployeeID = e.EmployeeID ' +
   'left join cust."Customers" c on o.CustomerID = c.CustomerID');

Mit der von mir immer wieder erwähnten Connection-Komponente hab ich die Eingangs gezeigte DB erstellt. Laut diesem Artikel ist dies somit die 'Hauptdatenbank' in dieser Verbindunng. Alle weiteren Datenbanken müssen nun also mit ATTACH der Verbindung hinzugefügt werden.
Dies hatte ich ja erstmal so versucht:

Delphi-Quellcode:
DMLSQLite.FDSQLiteConnection.Params.Add('ATTACH "ContentMasterData.sdb" AS "ContentMasterData";');


Tigerlilly meinte dazu:
Zitat:

DMLSQLite.FDSQLiteConnection.Params nimmt NUR angaben zur Verbindung zur Datenbank auf. Ein Attach hat da nichts verloren.
Im Screenshot ist eine Datenbank mit .db angegeben, im Code .sqlite. Ist das ein Typo?
Hmm, Tigerlilly, in welchem Screenshot? Die eingeschwärzten Bildschirmschüsse zeigen ewinen Ausschnitt meiner Programmoberfläche. Das kann ein Tippfehler sein, ist aber wohl eher ein C&P-Fehler.

Gemäss dem oben gezeigten Codeschnipselfund werde ich jetzt erstmal zusehen, dass ich die ATTACH-Anweisung richtig hinkrieg.

Zitat von Jobo:
Zitat:

Ich schätze das Problem hier ist:
Das verwendete Tool generiert ein Script, Delphi SQL Componenten arbeiten aber meist Statement basiert.
Was ist denn der Unterschied zwischen einem Script und einem SQL-Statement? Nach meiner Interpretation erstmal wohl keiner; beide sind reiner Asccii-Text und werden interpretiert.
Wobei ein VB-Interpreter mit Select wohl erst mal nicht viel anfangen kann, eine SQL-Engine hingegen mit Dim hingegen genauso überfordert ist. Wobei der VB-Interpreter ein Select-Statement als String entgegennehmen und ihn an die SQL-Engine weiterreichen kann.

So, wie ich das sehe, enthält dieses Script nichts weiter als ein mehr oder weniger komplexes SQL-Statement, um damit mit der SQLite-Engine (SQLite3.dll) eine SQLite-DB zu erstellen.

Im Anhang zeigt ein jpeg die auf meinem System gefundenen sqlite.exe-Dateien, wobei mindestens eine davon eine Installationsdatei ist.


Gruss
Delbor

TigerLilly 8. Sep 2017 10:42

AW: Automatiach erstellte Syntax
 
Ja, genau. Das ATTACH muss aber mit ExecSQL ausgeführt werden, nicht in den Params.

Der Unterschied zwischen SQL Abweisung und SQL Script ist nur, dass eine SQL Anweisung eine einzelne Anweisung ist, das Script aber aus mehreren Anweisungen besteht. In der Regel ist das für die Delphi Komponenten kein Unterschied, weil der ganze Text an die Datenbank zur Abarbeitung geschickt wird.

Ich habe es jetzt nicht im Kopf, aber es kann vereinzelt ein Problem mit einem Script geben, wenn Delphi das SQL Statement parsen muss, um zB Parameter zu setzen oder ein Update-SQL zu generieren. Oder wenn Feldnamen extrahiert werden müssen. Aber das ist da ja nicht der FAll.

Ich persönlich mag es lieber, wenn die Statements einzeln ausgeführt werden, dann sehe ich besser, wo ein Fehler auftritt + ich kann auch nach jedem Statement dem Benutzer Feedback geben + den Fortschritt anzeigen.

p80286 8. Sep 2017 11:00

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von Delbor (Beitrag 1380591)
Was ist denn der Unterschied zwischen einem Script und einem SQL-Statement? Nach meiner Interpretation erstmal wohl keiner; beide sind reiner Asccii-Text und werden interpretiert.

Ein Script enthält (meist) mehrere Statements. Z.B.
SQL-Code:
select * from table1;
delete from table2 where id=12345;
update table4 set wert=1234 where id=6789;
Zitat:

Zitat von Delbor (Beitrag 1380591)
Wobei ein VB-Interpreter mit Select wohl erst mal nicht viel anfangen kann, eine SQL-Engine hingegen mit Dim hingegen genauso überfordert ist. Wobei der VB-Interpreter ein Select-Statement als String entgegennehmen und ihn an die SQL-Engine weiterreichen kann.

Ich vermute, Da hast Du etwas mißverstanden.

Zitat:

Create A New Database

•At a shell or DOS prompt, enter: "sqlite3 test.db". This will create a new database named "test.db". (You can use a different name if you like.)


•Enter SQL commands at the prompt to create and populate the new database.


•Additional documentation is available here.

von https://sqlite.org/quickstart.html

Gruß
K-H

Edith:
Zitat:

Zitat von TigerLilly (Beitrag 1380592)
Ich habe es jetzt nicht im Kopf, aber es kann vereinzelt ein Problem mit einem Script geben, wenn Delphi das SQL Statement parsen muss, um zB Parameter zu setzen oder ein Update-SQL zu generieren. Oder wenn Feldnamen extrahiert werden müssen. Aber das ist da ja nicht der FAll.

Den Delphi-Query-Komponenten kannst Du nur Statements übergeben. Um ein Script zu verarbeiten benötigst Du die entsprechende DB-Shell.

jobo 8. Sep 2017 11:27

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von TigerLilly (Beitrag 1380592)
Der Unterschied zwischen SQL Abweisung und SQL Script ist nur, dass eine SQL Anweisung eine einzelne Anweisung ist, das Script aber aus mehreren Anweisungen besteht. In der Regel ist das für die Delphi Komponenten kein Unterschied, weil der ganze Text an die Datenbank zur Abarbeitung geschickt wird.

Der Unterschied scheint recht klein zu sein, einfach mehr von dem gleichen, aber die Konsequenzen sind leider so, dass die meisten Delphi SQL Komponenten keine Scripte verarbeiten. Das ist nicht mal nur bei Delphi so.

Und wenn man nun Delphi Componenten nutzt, die gewisse Datenbank-Features als Attribute anbieten, Transaktionseinstellungen, i18 settings usw, dann dürfte klar sein, dass es Probleme gibt, wenn man in einem Script oder auch nur einer einzelnen SQL Query widersprechende Anweisungen absetzt.

Delbor 8. Sep 2017 12:18

AW: Automatiach erstellte Syntax
 
Hi zusammen

Ich hab das mal so umgesetzt:
Delphi-Quellcode:
procedure TDMLSQLite.ContentmasterDBCreate;
  var SQLString: String;
begin
  try
    DMLSQLite.FDSQLiteConnection.Connected := false;
    FDSQLiteConnection.ExecSQL('ATTACH "M:\SQLite-DB Corner\ContentMasterData\ContentMasterData.sqlite" AS ContentMasterData');
//    DMLSQLite.FDSQLiteConnection.Params.Values['Database']:='"M:\SQLite-DB Corner\ContentMasterData\ContentMasterData.sqlite"';

// War obige Zeile nicht auskommentiert: Unbekannte Datenbank. Danach liefen alle Createanweisungen durch. Beim nächsten ExecCSQL krachte es

    DMLSQLite.FDSQLiteConnection.Params.Values['FailIfMissing']:='False';
    DMLSQLite.FDSQLiteConnection.Params.Values['PRAGMA foreign_keys']:='ON';
    SQLiteTestMain.LBxPathlist.Items.AddStrings(FDSQLiteConnection.Params);
    DMLSQLite.FDSQLiteConnection.Connected := true;
    DMLSQLite.FDSQLiteConnection.GetInfoReport(SQLiteTestMain.Memo1.Lines);
    SQLString := '';
    SQLString := Createbilddescribetabelle;
    SQLString := SQLString + Createbilddescribetabelle_has_HtmlTabell;
    SQLString := SQLString + Createbildtabelle;
    SQLString := SQLString + CreateCSSTabelle;
    SQLString := SQLString + Creategalerietabelle;
    SQLString := SQLString + CreateHTMLTable;
    SQLString := SQLString + CreateJavascriptTable;
    SQLString := SQLString + Createkategorien_tabelle;
    SQLString := SQLString + Createkategorien_tabelle_has_bildDescribeTabelle;
    SQLString := SQLString + CreateMenueTabelle;
    SQLString := SQLString + CreateSubMenue2Table;
    SQLString := SQLString + CreateSubmenuetabelle;
    DMLSQLite.FDSQLiteConnection.ExecSQL(SQLString);
  except
    on E: EDatabaseError do
     ShowMessage('Exception raised with message' + E.Message);
  end;
end;
Wie gesagt: Beim 2. ExecSQL krachte es. Hmm, ich bin mir jetzt nicht mehr sicher, aber ich glaube mich an ein Tut zu erinnern, dass nach jeder Create-Anweisung ein ExecSQL durchführte. Der Grund könnte sein: Durch meine Aufteilung der einzelnen TableCreate-Statements und deren wiederzusammenführung in einem einzelnen SQLString hab ich wohl Leerzeichen zwischen den einzelnnen Anmweisungen entfernt, so dass da nun Konstrukte vorhanden sind wie
Zitat:

"...("CSS-Tabelle_idCSS");''CREATE TABLE "ContentMasterData..."
Und damit dürfte wohl jede SQL-Engine so ihre Probleme haben. Wobei auch das ein Grund sein könnte:
Zitat:

aber die Konsequenzen sind leider so, dass die meisten Delphi SQL Komponenten keine Scripte verarbeiten.
Gestern abend habe ich mir mal den Codevorschlag von nahpets (#24) runtergeladen. Ich werdes mal mit dem probieren.

Gruss
Delbor

nahpets 8. Sep 2017 12:59

AW: Automatiach erstellte Syntax
 
Bei Deinem 2. ExecSQL führst Du irgendwas aus, was aus mehreren Strings zusammengesetzt ist.

Da uns der Inhalt nicht bekannt ist, ist es annähernd unmöglich, hier irgendwie brauchbare Hilfestellung zu geben.

Normalerweise kann ExecSQL (wie oben schon angemerkt) nur ein Statement, also z. B. das Create von einer Tabelle, ein einzelnes Insert, ein einzelnes Update ..., aber keine Abfolge von mehr oder weniger Statments: Sprich: (höchstwahrscheinlich) keine Scripte.
Zitat:

"...("CSS-Tabelle_idCSS");''CREATE TABLE "ContentMasterData..."
Da ist mit vollkommen unklar, welches " jetzt am Anfang eines Statements, eines Wertes ... steht und welches am Ende. Wenn man sich das dann auch nochmal per Copy&Paste in 'nen Editor holt, erkennt man, dass dort einfach und doppelte Hochkommata schön gemischt sind.

Wenn die Anzahl der " beim Zusammenbau des SQLString aus einer Vielzahl weiterer Strings nicht so ganz zusammen passt, kann das zu diversen Fehlern führen, die man anhand der Fehlermeldung allein niemals finden und beheben kann.
Dann werden da mehrere String hintereinander gehängt, ist jeder ein vollständiges Statement, bei dem auch sichergestellt ist, dass es mit ; endet?

Meine Regel ist: Ein Statement ein ExecSQL (auch dann, wenn ich es anders lösen könnte). Dadurch weiß ich im Fehlerfalle immer, welches Statement den Fehler auslöste und muss nicht ggfls. tausende von Zeilen durchsuchen, um irgendwo einen Fehler zu finden.

Möchte man z. B. im Zusammenhang mit einer Firebird-Datenbank mehrere Statements als Script per ExecSQL ausführen, muss man es in dieser Art machen:
SQL-Code:
EXECUTE BLOCK AS BEGIN
  Statement_1;
...
  Statement_n;
END
Andernfalls erntet man bestenfalls nur 'ne Fehlermeldung.
Ob SQLite sowas unterstützt, weiß ich nicht.

Delbor 8. Sep 2017 13:37

AW: Automatiach erstellte Syntax
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi zusammen

Der Abruch erfolgt gleich im erstem Statementt: (Hier das 2.)
Delphi-Quellcode:
function TDMLSQLite.Createkategorien_tabelle:String;
 var SQLString: String;
begin
  SQLString := 'CREATE TABLE "ContentMasterData"."kategorien_tabelle"('+
                            '"Kath_ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("Kath_ID">=0),'+
                            '"Kategorie" VARCHAR(120) NOT NULL);';
  Result := SQLString;
end;

function TDMLSQLite.Createbilddescribetabelle :String;
 var SQLString: String;
begin
  SQLString := 'CREATE TABLE ContentMasterData.bilddescribetabelle('+
                                '"BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("BilddesribeID">=0),'+
                                '"bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild">=0),'+
                                '"bildkatID" INTEGER NOT NULL CHECK("bildkatID">=0),'+
                                '"bildname" VARCHAR(45),"Dateipfad" VARCHAR(250),"bildbeschreibung" VARCHAR(800),'+
                                '"bildlegende" VARCHAR(300),"Author" VARCHAR(250),'+
                                'CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" '+
                                  'FOREIGN KEY("bildtabelle_idBild")'+
                                  'REFERENCES "bildtabelle"("idBild"));'+
  'CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx" ON"bilddescribetabelle" ("bildtabelle_idBild");';
  Result := SQLString;
end;
Wie man hier sieht, habe ich im unteren Statement in der 1. Zeile die doppelten Anführungszeichen entfernt. Allerdings erst vor einemm zweiten Durchlauf. Die Fehlermeldung lautete zwar gleich, aber der Datenbankname endete diesmal mit einem Hochkomma.
Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: unknown database ContentMasterData' aufgetreten.
---------------------------
Dann hab ich noch einen draufgesetzt und die Datenbankbezeichnung weggelassen. Das Statement jetzt:
Delphi-Quellcode:
  SQLString := 'CREATE TABLE "bilddescribetabelle"('+
                                '"BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("BilddesribeID">=0),'+
                                '"bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild">=0),'+
                                '"bildkatID" INTEGER NOT NULL CHECK("bildkatID">=0),'+
                                '"bildname" VARCHAR(45),"Dateipfad" VARCHAR(250),"bildbeschreibung" VARCHAR(800),'+
                                '"bildlegende" VARCHAR(300),"Author" VARCHAR(250),'+
                                'CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" '+
                                  'FOREIGN KEY("bildtabelle_idBild")'+
                                  'REFERENCES "bildtabelle"("idBild"));'+
  'CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx" ON"bilddescribetabelle" ("bildtabelle_idBild");';
  Result := SQLString;
end;
Und die Fehlermeldung, als der Index erzeug werden sollte:
Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: table "bilddescribetabelle" already exists' aufgetreten.
---------------------------
Im Anhang zeigt ein Jpeg die im SQLExpert geöffnete Datenbank....

Ja, ich denk, dann werd' ich mal...


Gruss
Delbor

nahpets 8. Sep 2017 14:15

AW: Automatiach erstellte Syntax
 
Je nach Datenbank muss ein Name eindeutig sein, es darf also keine Tabelle mit dem Namen bilddescribetabelle und gleichzeitig einen Index mit dem Namen bilddescribetabelle geben.
Auch dürfen die Namen, je nach Datenbank, nur eine bestimmte Länge haben (häufig 30 Zeichen).

Funktioniert statt:
SQL-Code:
'CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx" ON "bilddescribetabelle" ("bildtabelle_idBild");';


eventuell dieses hier:
SQL-Code:
'CREATE INDEX "ContentMasterData"."fk_bilddescribetabelle_bildtabelle1_idx" ON "bilddescribetabelle" ("bildtabelle_idBild");';


Muss in den Tabellennamen immer auch noch tabelle drinstehen?
Wenn nein, lass das weg, dann werden die Namen deutlich kürzer oder wenn Du bei Fremdschlüsseln ein fk_ davorstellst und beim Index ein _idx hinten anhängst, dann lass Tabellennamen mit t_ beginnen, Views können dann mal mit v_ beginnen ...

Sind die Unmengen von " bei SQLite tatsächlich bei der Angabe der Bezeichner erforderlich? Je nach Datenbank benötigt man das, wenn man die Bezeichner zwingend casesensitiv haben will, ohne die " wäre Groß-/Kleinschreibung dann egal. Aber das scheint nicht einheitlich zu sein.

Bei den Änderungen ist mir durchaus klar, dass sie dann nicht zur die Scripte betreffen, sondern sich auch durch die von Dir schon erstellte Applikation ziehen. Der Änderungsaufwand könnten dann auch einen unüberschaubaren Rattenschwanz nach sich ziehen. Da wären dann erstmal Aufwand und Nutzen abzuwägen.

Delbor 8. Sep 2017 14:19

AW: Automatiach erstellte Syntax
 
Hi nahpeds

Zitat:

"...("CSS-Tabelle_idCSS");''CREATE TABLE "ContentMasterData..."
Das dient eigentlich nur der Demonstration dessen, was im SQLString stehen muss, wenn ich ihn mit den Ergebnissen der einzelnen Funktionen zusammensetze.
Zitat:

Bei Deinem 2. ExecSQL führst Du irgendwas aus, was aus mehreren Strings zusammengesetzt ist.
Ja eben - und dies auch noch ohne Leerzeichen dazwischen.
Zitat:

Normalerweise kann ExecSQL (wie oben schon angemerkt) nur ein Statement, also z. B. das Create von einer Tabelle, ein einzelnes Insert, ein einzelnes Update ..., aber keine Abfolge von mehr oder weniger Statments: Sprich: (höchstwahrscheinlich) keine Scripte.
Selbst wenn ExecSQL mehr als ein Statement ausführen könnte - wie soll er die unterscheiden, wenn weder ein Leerzeichen oder sonst ein bestimmtes Steuerzeichen zwischen den einzelnen Statements steht? Der anfangs zitierte String ist das Ende des einen und der Beginn eines andern Statements.
Zitat:

Meine Regel ist: Ein Statement ein ExecSQL (auch dann, wenn ich es anders lösen könnte). Dadurch weiß ich im Fehlerfalle immer, welches Statement den Fehler auslöste und muss nicht ggfls. tausende von Zeilen durchsuchen, um irgendwo einen Fehler zu finden.
Und die ist mit Sicherheit goldrichtig. Denn wie gesagt: In meinem letzten Post habe ich die Prozeduren eingesetzt, die du gestern gepostet hast.
So, wies nun ausieht, muss, bzw. darf ich die Datenbank in den einzelnen Statements gar nicht mehr anführen. Und was das mit den diversen Hochkommas auf sich hat, wird sich zeigen. Die Dinger sind möglicherweise bei Namen, die Leerzeichen enthalten (ich glaub, das steht auch irgendwo hier) zwingen, bei Namen andreseits aber nicht störend.
Delphi-Quellcode:
'CREATE TABLE "bilddescribetabelle"('+
Das wurde anstandslos ausgeführt.


Gruss
Delbor

jobo 8. Sep 2017 14:30

AW: Automatiach erstellte Syntax
 
Zitat:

Zitat von Delbor (Beitrag 1380630)
Wie man hier sieht, habe ich im unteren Statement in der 1. Zeile die doppelten Anführungszeichen entfernt. Allerdings erst vor einemm zweiten Durchlauf. Die Fehlermeldung lautete zwar gleich, aber der Datenbankname endete diesmal mit einem Hochkomma.

Dann hab ich noch einen draufgesetzt und die Datenbankbezeichnung weggelassen. Das Statement jetzt:
Delphi-Quellcode:
  SQLString := 'CREATE TABLE "bilddescribetabelle"('+
                                '"BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("BilddesribeID">=0),'+
                                '"bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild">=0),'+
                                '"bildkatID" INTEGER NOT NULL CHECK("bildkatID">=0),'+
                                '"bildname" VARCHAR(45),"Dateipfad" VARCHAR(250),"bildbeschreibung" VARCHAR(800),'+
                                '"bildlegende" VARCHAR(300),"Author" VARCHAR(250),'+
                                'CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" '+
                                  'FOREIGN KEY("bildtabelle_idBild")'+
                                  'REFERENCES "bildtabelle"("idBild"));'+
  'CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx" ON"bilddescribetabelle" ("bildtabelle_idBild");';
  Result := SQLString;
end;
Und die Fehlermeldung, als der Index erzeug werden sollte:
Zitat:

---------------------------
Im Projekt SQLiteTestProject.exe ist eine Exception der Klasse ESQLiteNativeException mit der Meldung '[FireDAC][Phys][SQLite] ERROR: table "bilddescribetabelle" already exists' aufgetreten.
---------------------------
Im Anhang zeigt ein Jpeg die im SQLExpert geöffnete Datenbank....

Ja, ich denk, dann werd' ich mal...

Was wirst Du nun ... ? Die Koffer packen? Wochenende beginnen?
Irgendwie gibst Du Dich doch sehr beratungsresistent.
Wenn Du Deine DB nicht abräumst vor einem 2. Versuch, muss es wohl knallen, beim erneuten Anlegen eines bereits bestehenden Objekts.
Wenn Du trotz mehrfacher Hinweise mehrere Statements in einen Aufruf packst, was soll man da noch raten?
2 Statements werden über ; getrennt.

nahpets 8. Sep 2017 14:43

AW: Automatiach erstellte Syntax
 
SQL-Statments enden (für gewöhnlich) mit einem Semikolon, das ist der Trenner. Ein Leerzeichen zwischen mehreren Statements ist (technisch) nicht erforderlich. Zur besseren Lesbarkeit gilt bei mir: Ein Statemnt, eine Zeile. Muss ein Statement auf mehrere Zeilen verteilt werden, dann kommt auch noch eine Leerzeile dazwischen.

Technisch kann man alles weglassen, was zur besseren Lesbarkeit führt, kann also z. B. ein Script von 10 MB durchaus als Einzeiler schreiben. Kann man, muss man aber nicht.

Auch wenn es mehr Aufwand ist, mache ich sowas
Delphi-Quellcode:
function TDMLSQLite.Createbilddescribetabelle :String;
 var SQLString: String;
begin
  SQLString := 'CREATE TABLE ContentMasterData.bilddescribetabelle('+
                                '"BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("BilddesribeID">=0),'+
                                '"bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild">=0),'+
                                '"bildkatID" INTEGER NOT NULL CHECK("bildkatID">=0),'+
                                '"bildname" VARCHAR(45),"Dateipfad" VARCHAR(250),"bildbeschreibung" VARCHAR(800),'+
                                '"bildlegende" VARCHAR(300),"Author" VARCHAR(250),'+
                                'CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" '+
                                  'FOREIGN KEY("bildtabelle_idBild")'+
                                  'REFERENCES "bildtabelle"("idBild"));'+
  'CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx" ON"bilddescribetabelle" ("bildtabelle_idBild");';
  Result := SQLString;
end;
lieber eher so:
Delphi-Quellcode:
function TDMLSQLite.Createbilddescribetabelle :String;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add('CREATE TABLE ContentMasterData.bilddescribetabelle');
  sl.Add('(');
  sl.Add(' "BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ');
  sl.Add('                 CHECK("BilddesribeID" >= 0),');
  sl.Add(' "bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild" >= 0),');
  sl.Add(' "bildkatID" INTEGER NOT NULL CHECK("bildkatID" >= 0),');
  sl.Add(' "bildname" VARCHAR(45),');
  sl.Add(' "Dateipfad" VARCHAR(250),');
  sl.Add(' "bildbeschreibung" VARCHAR(800),');
  sl.Add(' "bildlegende" VARCHAR(300),');
  sl.Add(' "Author" VARCHAR(250),');
  sl.Add(' CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" ');
  sl.Add(' FOREIGN KEY("bildtabelle_idBild")');
  sl.Add(' REFERENCES "bildtabelle"("idBild")');
  sl.Add(');');
  sl.Add('CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx"');
  sl.Add('         ON "bilddescribetabelle" ("bildtabelle_idBild");');
  Result := sl.Text;
  sl.Free;
end;
Und das geht nur, wenn man mehrere Statements bei SQLite mit ExecSQL ausführen kann, sonst musst Du dadraus mehrere Funktionen machen, eine für's Create Table und eine für Create Index.

Also eher sowas:
Delphi-Quellcode:
function TDMLSQLite.Create_BilddescribeTabelle :String;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add('CREATE TABLE ContentMasterData.bilddescribetabelle');
  sl.Add('(');
  sl.Add(' "BilddesribeID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ');
  sl.Add('                 CHECK("BilddesribeID" >= 0),');
  sl.Add(' "bildtabelle_idBild" INTEGER NOT NULL CHECK("bildtabelle_idBild" >= 0),');
  sl.Add(' "bildkatID" INTEGER NOT NULL CHECK("bildkatID" >= 0),');
  sl.Add(' "bildname" VARCHAR(45),');
  sl.Add(' "Dateipfad" VARCHAR(250),');
  sl.Add(' "bildbeschreibung" VARCHAR(800),');
  sl.Add(' "bildlegende" VARCHAR(300),');
  sl.Add(' "Author" VARCHAR(250),');
  sl.Add(' CONSTRAINT "fk_bilddescribetabelle_bildtabelle1" ');
  sl.Add(' FOREIGN KEY("bildtabelle_idBild")');
  sl.Add(' REFERENCES "bildtabelle"("idBild")');
  sl.Add(');');
  Result := sl.Text;
  sl.Free;
end;

function TDMLSQLite.Create_fk_bilddescribetabelle_bildtabelle1_idx :String;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  sl.Add('CREATE INDEX "ContentMasterData"."bilddescribetabelle.fk_bilddescribetabelle_bildtabelle1_idx"');
  sl.Add('         ON "bilddescribetabelle" ("bildtabelle_idBild");');
  Result := sl.Text;
  sl.Free;
end;
Bitte prüfe als Erstes: Kann man bei SQLite mehrere SQL in einem ExecSQL ausführen?

Wenn nein, dann baue zuerst entsprechende Funktionen, je Statement eine.

Also pro SQL darf es nur ein ; geben.

Delbor 8. Sep 2017 15:04

AW: Automatiach erstellte Syntax
 
Hi nahpeds
Zitat:

Muss in den Tabellennamen immer auch noch tabelle drinstehen?
Wenn nein, lass das weg, dann werden die Namen deutlich kürzer oder wenn Du bei Fremdschlüsseln ein fk_ davorstellst und beim Index ein _idx hinten anhängst, dann lass Tabellennamen mit t_ beginnen, Views können dann mal mit v_ beginnen ...
Wenn ich das ändere, dann muss ich das zuallererst im DB-Modell in Workbench tun und dann konsequent durch alles hindurch durchziehen. Wenn ich das mit der Zeit vergleiche, die ich bis jetzt damit verbracht habe, meine MySQL-DB in SQLite zu erstellen, so würde das ändern aller Namen wohl ein vielfaches der bisher eingesetzten Zeit beanspruchen. Dasschlimmste sind die Namen der Zwischentabellen - die hätten wohl glat Einträge im Guinnesbuch der Rekorde für die längsten Namen verdient.

Zitat:

Sind die Unmengen von " bei SQLite tatsächlich bei der Angabe der Bezeichner erforderlich? Je nach Datenbank benötigt man das, wenn man die Bezeichner zwingend casesensitiv haben will, ohne die " wäre Groß-/Kleinschreibung dann egal. Aber das scheint nicht einheitlich zu sein.
Ich weiss es bislang auch nicht wirklich. Embarcadero benutzt in mindestens eiem Tut sogar 2 einzelne Hochkommas...

Zitat:

Bei den Änderungen ist mir durchaus klar, dass sie dann nicht zur die Scripte betreffen, sondern sich auch durch die von Dir schon erstellte Applikation ziehen. Der Änderungsaufwand könnten dann auch einen unüberschaubaren Rattenschwanz nach sich ziehen. Da wären dann erstmal Aufwand und Nutzen abzuwägen.
Sagen wir's mal so: seit ich mir schon vor längere Zeit eine neue Kiste und die jetzige Delphi-Version angeschafft habe, bin ich eigentlich nur noch mit dem DB-Zeugs beschäftigt. Etwas vom wohl wichtigsten war die Umstellung von DBExpress nach Firedac. Und dann kam die Idee der von mir so genannten "SatellitenDatenbanken" auf, die in Zukunft die Rohbilder und die Bitmaps aufnemen sollen. Die Dinger sind mir einfach zu gross, um sie wirklich in der Hauptdatenbank zu speichern.
Und so kommt irgendwann mal der Punkt, wo ich sagen muss: Jetzt lass ich das mal so und arbeite am eigentlichen Programm weiter.
Ich hab auch grad gesehen: die Doppelten Hochkommas wurdenso von Workbench exportiert. Das scheint mal so,als ob sich da nicht viel machen lässt...

Gruss
Delbor

PS: Mal etwas mehr oftopic:
In den MySQL Workbench-Einstellungen sind die FK-Namensregelung so definiert: fk_%stable%_%dtable%,
für Spaltennamen so: %table%_%column%. Da seh ich eigentlich keinen grossen Spielraum, wenn man sprechende Namen verwenden will...


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:07 Uhr.
Seite 1 von 2  1 2      

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