Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Interbase SQL-Dialect 1/3 - Problem (https://www.delphipraxis.net/178096-interbase-sql-dialect-1-3-problem.html)

wendelin 18. Dez 2013 00:22

Datenbank: Interbase • Version: 6 • Zugriff über: SQL

Interbase SQL-Dialect 1/3 - Problem
 
Hallo,
Ich lege eine neue Datenbank nicht mit der IBConsole oder mit Script's sondern ausschliesslich aus Delphi heraus an. Ebenso ALLE Tabellen.

Siehe Quellcode:
Delphi-Quellcode:

(*  DataBase + Tables anlegen DataBase + Tables anlegen *)
          (*  TEIL1 --- TEIL1 --- TEIL1  *)
(******************************************************************************)
 procedure TForm3.SpeedButton9Click(Sender: TObject);
(******************************************************************************)
VAR DBPath : STRING;
const
  cCreateTxt = ' %d. Versuch: Datenbank wird erstellt...';
  cReadyTxt = 'Datenbank wurde erstellt!';
begin
  If not FileExists(g_DBPfad + '\My_IB_DB.gdb') then
  begin
    DBPath := g_DBPfad + '\My_IB_DB.gdb';
    EditDBPath.Text := DBPath;
    EditDBPath.Refresh;
    Screen.Cursor := crHourGlass;
    If DataModule2.IBD.LoginPrompt = TRUE THEN DataModule2.IBD.LoginPrompt := FALSE;
    IF DataModule2.IBD.Connected  = TRUE THEN DataModule2.IBD.Connected  := FALSE;
    DataModule2.IBD.Params.Clear;
    try
      try
        StatusBar.SimpleText := Format(cCreateTxt, [1]);
        StatusBar.Refresh;
        with DataModule2.IBD do
        begin
          DatabaseName := EditDBPath.Text;      
          Params.Add(Format('USER "%s"', [EditUserName.Text]));
          Params.Add(Format('PASSWORD "%s"', [EditPassword.Text]));
   -->   SQLDialect:=1;                                 // (3 ?)geht nicht mit
          Params.Add('PAGE_SIZE 4096');                  // SQLDialect'3'-->
          Params.Add('DEFAULT CHARACTER SET ISO8859_1'); // wahrscheinlich wegen
          CreateDatabase;                                // Double-Quotes o.ä!!
        end;
        StatusBar.SimpleText := cReadyTxt;
        Tables_anlegen;                                  // Tabellen werden angelegt
        SpeedButton9.Enabled := False;
        except
        on E:EDatabaseError do
        begin
          MessageBeep(MB_ICONEXCLAMATION);
          MessageDlg(E.Message, mtError, [mbOk], 0);
        end;
      end;
      finally
      Screen.Cursor := crDefault;
    end;
  end ELSE ShowMessage(' Die Datenbank existiert schon !');
end;
Meine Frage : Warum funktioniert nur die Anlage der IBDB im SQL-Dialect 1, aber nicht in Dialect 3?
In (Tedit)[EditUserName.Text] steht SYSDBA; in (Tedit)[EditPassword.Text] masterkey (Property PasswordChar '*********'. Auch wenn ich die Zeile (mit Pfeil) komplett heraus nehme und im Object-Inspector SQL-Dialect auf '3' setzte kommt die RunTime-Fehlermeldung : token unknown line 1 char 94
"SYSDBA".

-----------------------------------------------------------------------------------------------

Ferner habe ich noch eine allgemeine Frage: Wie kann ich meine Beiträge (Fragen) als "Erledigt"
kennzeichnen ? :freak:

Hansa 18. Dez 2013 01:49

AW: Interbase SQL-Dialect 1/3 - Problem
 
Warum wird das so gemacht :

Zitat:

Zitat von wendelin (Beitrag 1240160)
...nicht mit der IBConsole oder mit Script's sondern ausschliesslich aus Delphi heraus an. Ebenso ALLE Tabellen.

Wenn dann nämlich so eine Fehlermeldung kommt :

Code:
token unknown line 1 char 94
"SYSDBA".
Wo ist nun die Zeile 94 ? Die gilt für die DB, nicht für Dein Programm! Welches SQL-Script wird denn nun erzeugt ? Sieht für mich so aus, dass da in erster Zeile "USER" steht. Am Anfang dürften aber nur SETs usw. da stehen und dann kommt irgendwann "create". In Delphi allerdings schwer nachzuvollziehen. 8-)

Sir Rufo 18. Dez 2013 01:54

AW: Interbase SQL-Dialect 1/3 - Problem
 
Ein paar Anmerkungen zu deinem Code
  • Das hier
    Delphi-Quellcode:
        If DataModule2.IBD.LoginPrompt = TRUE THEN DataModule2.IBD.LoginPrompt := FALSE;
        IF DataModule2.IBD.Connected = TRUE THEN DataModule2.IBD.Connected := FALSE;
    kannst du auch so schreiben
    Delphi-Quellcode:
        DataModule2.IBD.LoginPrompt := FALSE;
        DataModule2.IBD.Connected := FALSE;
  • das hier
    Delphi-Quellcode:
    Screen.Cursor := ...;
    Foo; // Hier kommt eine Exception und der Cursor wird nicht zurückgesetzt!
    try
      Bar;
    finally
      Screen.Cursor := ...;
    end;
    eher so
    Delphi-Quellcode:
    Screen.Cursor := ...;
    try
      Foo; // kann kommen was will, der Cursor wird zurückgesetzt
      Bar;
    finally
      Screen.Cursor := ...;
    end;
  • und hier
    Delphi-Quellcode:
    try
      Foo;
      Bar;
    except
      on E:EDatabaseError do
        begin
          MessageBeep(MB_ICONEXCLAMATION);
          MessageDlg(E.Message, mtError, [mbOk], 0);
        end;
    end;
    machst du das Gleiche, was bei einer normalen (ungefangenen) Exception auch passiert.
    Es wird eine Messagebox mit dem Fehler angezeigt. Allerdings wird bei dir der Code nach
    Delphi-Quellcode:
    except ... end;
    noch weiter ausgeführt.

    Es passiert hier nur deswegen nichts, weil danach nur noch Zeilen kommen, die auch bei einer Exception ausgeführt werden.

    So behandelt man Exceptions nicht.

    kannst du also auch so vereinfachen (verbessern)
    Delphi-Quellcode:
    Foo;
    Bar;
Zum eigentlichen Thema:

Wenn du uns das Script zeigst, dann können wir evtl. auch die Frage beantworten.

Offene Fragen schließen:

Schreibe eine Antwort und entferne unten den Haken bei "Dieses Thema als offene Frage markieren"

mkinzler 18. Dez 2013 06:44

AW: Interbase SQL-Dialect 1/3 - Problem
 
Zitat:

Code:
token unknown line 1 char 94
"SYSDBA".
Wo ist nun die Zeile 94 ?
Hier sthet nichts von Zeile 94 sondern Zeile 1 Zeichen 94

IBExpert 18. Dez 2013 08:47

AW: Interbase SQL-Dialect 1/3 - Problem
 
weil im Dialekt 1 die Nutzung von " und ' gleichwertig ist und im Dialekt 3 " für Objektnamen und ' für Strings benutzt wird. Der Username Sysdba ist ein String und muß daher mit ' abgegrenzt werden. Das wäre aber weiterhin auch zum Dialekt 1 kompatibel

Sir Rufo 18. Dez 2013 09:29

AW: Interbase SQL-Dialect 1/3 - Problem
 
Wenn du das etwas umstrukturierst, dann wird das auch übersichtlicher und besser dokumentiert:

In
Delphi-Quellcode:
TForm3
folgendes rein:
Delphi-Quellcode:
  // Wir wollen etwas in die StatusBar schreiben
  procedure TForm3.SetStatus( const AText : string );
    begin
      StatusBar.SimpleText := AText;
      StatusBar.Refresh;
    end;

  procedure TForm3.SpeedButton9Click( Sender : TObject );
    begin
      EditDBPath.Text := g_DBPfad + '\My_IB_DB.gdb';
      // Das DataModule kümmert sich um die Anlage der Datenbank
      // Um StatusMeldungen an die Form zu liefern, nehmen wir die Methode SetStatus als Callback ;o)
      DataModule2.CreateDataBase( EditDBPath.Text, EditUserName.Text, EditPassword.Text, SetStatus );
    end;
In
Delphi-Quellcode:
TDataModule2
werden die Methoden
Delphi-Quellcode:
CreateDatabase
und
Delphi-Quellcode:
CreateTables
angelegt
Delphi-Quellcode:
  // Eine Callback-Methode für Status-Meldungen
  type
    TStatusCallback = procedure( const AStatus : string ) of object;

  procedure TDataModule2.CreateTables( StatusCallback : TStatusCallback );
    begin
      // whatever
    end;

  procedure TDataModule2.CreateDataBase( const DBPath, Username, Password : string; StatusCallback : TStatusCallback );
    const
      cCreateTxt  = ' %d. Versuch: Datenbank wird erstellt...';
      cReadyTxt   = 'Datenbank wurde erstellt!';
      cFailureText = 'Datenbank konnte nicht erstellt werden!';
    begin
      if FileExists( DBPath )
      then
        // Keine Meldung ausgeben, sondern eine Exception
        // Dadurch kommt die Meldung eh ;o)
        raise Exception.CreateFmt( 'Die Datenbank "%s" existiert schon', DBPath );

      Screen.Cursor := crHourGlass;
      try
        IBD.LoginPrompt := FALSE;
        IBD.Connected  := FALSE;
        IBD.Params.Clear;

        // StatusMeldung (Callback-Methode aufrufen)
        StatusCallback( Format( cCreateTxt, [1] ) );

        try

          IBD.DatabaseName := DBPath;
          IBD.Params.Add( Format( 'USER "%s"', [Username] ) );
          IBD.Params.Add( Format( 'PASSWORD "%s"', [Password] ) );
          IBD.SQLDialect := 1;
          IBD.Params.Add( 'PAGE_SIZE 4096' );
          IBD.Params.Add( 'DEFAULT CHARACTER SET ISO8859_1' );
          IBD.CreateDataBase;

          // StatusMeldung (Callback-Methode aufrufen)
          StatusCallback( cReadyTxt );

          // Tables_anlegen; // Tabellen werden angelegt
          CreateTables( StatusCallback );

        except
          on E : Exception do
            begin
              if FileExists( DBPath )
              then
                DeleteFile( DBPath );

              // StatusMeldung (Callback-Methode aufrufen)
              StatusCallback( cFailureText );

              raise;
            end;
        end;

      finally
        Screen.Cursor := crDefault;
      end;
    end;
Und damit ist in
Delphi-Quellcode:
TForm3.SpeedButton9Click
auf einen Blick klar, was da passiert -> Es wird eine Datenbank angelegt (Documentation by Code). Vorher musste man sich erst durch den Quellcode wühlen, um das festzustellen.

wendelin 18. Dez 2013 09:58

AW: Interbase SQL-Dialect 1/3 - Problem
 
Zitat:

Zitat von IBExpert (Beitrag 1240191)
weil im Dialekt 1 die Nutzung von " und ' gleichwertig ist und im Dialekt 3 " für Objektnamen und ' für Strings benutzt wird. Der Username Sysdba ist ein String und muß daher mit ' abgegrenzt werden. Das wäre aber weiterhin auch zum Dialekt 1 kompatibel

Danke für Deine Antwort. Aber: wenn ich in Edit anstatt SYSDBA --> 'SYSDBA' eingebe meckert der
Compiler ->> funktioniert also auch nicht ( your UserName and Password are not defined)!
NaJa was solls, Dialect 1 funktioniert ja.

DeddyH 18. Dez 2013 10:05

AW: Interbase SQL-Dialect 1/3 - Problem
 
Delphi-Quellcode:
Params.Add(Format('USER %s', [QuotedStr(EditUserName.Text)]));
oder auch
Delphi-Quellcode:
Params.Add(Format('USER ''%s''', [EditUserName.Text]));
, dann meckert der Compiler nicht mehr, und Du hast Deine Hochkommata.

wendelin 18. Dez 2013 10:07

AW: Interbase SQL-Dialect 1/3 - Problem
 
Zitat:

Zitat von Sir Rufo (Beitrag 1240194)
Wenn du das etwas umstrukturierst, dann wird das auch übersichtlicher und besser dokumentiert:

In
Delphi-Quellcode:
TForm3
folgendes rein:
Delphi-Quellcode:
  // Wir wollen etwas in die StatusBar schreiben
  procedure TForm3.SetStatus( const AText : string );
    begin
      StatusBar.SimpleText := AText;
      StatusBar.Refresh;
    end;

  procedure TForm3.SpeedButton9Click( Sender : TObject );
    begin
      EditDBPath.Text := g_DBPfad + '\My_IB_DB.gdb';
      // Das DataModule kümmert sich um die Anlage der Datenbank
      // Um StatusMeldungen an die Form zu liefern, nehmen wir die Methode SetStatus als Callback ;o)
      DataModule2.CreateDataBase( EditDBPath.Text, EditUserName.Text, EditPassword.Text, SetStatus );
    end;
In
Delphi-Quellcode:
TDataModule2
werden die Methoden
Delphi-Quellcode:
CreateDatabase
und
Delphi-Quellcode:
CreateTables
angelegt
Delphi-Quellcode:
  // Eine Callback-Methode für Status-Meldungen
  type
    TStatusCallback = procedure( const AStatus : string ) of object;

  procedure TDataModule2.CreateTables( StatusCallback : TStatusCallback );
    begin
      // whatever
    end;

  procedure TDataModule2.CreateDataBase( const DBPath, Username, Password : string; StatusCallback : TStatusCallback );
    const
      cCreateTxt  = ' %d. Versuch: Datenbank wird erstellt...';
      cReadyTxt   = 'Datenbank wurde erstellt!';
      cFailureText = 'Datenbank konnte nicht erstellt werden!';
    begin
      if FileExists( DBPath )
      then
        // Keine Meldung ausgeben, sondern eine Exception
        // Dadurch kommt die Meldung eh ;o)
        raise Exception.CreateFmt( 'Die Datenbank "%s" existiert schon', DBPath );

      Screen.Cursor := crHourGlass;
      try
        IBD.LoginPrompt := FALSE;
        IBD.Connected  := FALSE;
        IBD.Params.Clear;

        // StatusMeldung (Callback-Methode aufrufen)
        StatusCallback( Format( cCreateTxt, [1] ) );

        try

          IBD.DatabaseName := DBPath;
          IBD.Params.Add( Format( 'USER "%s"', [Username] ) );
          IBD.Params.Add( Format( 'PASSWORD "%s"', [Password] ) );
          IBD.SQLDialect := 1;
          IBD.Params.Add( 'PAGE_SIZE 4096' );
          IBD.Params.Add( 'DEFAULT CHARACTER SET ISO8859_1' );
          IBD.CreateDataBase;

          // StatusMeldung (Callback-Methode aufrufen)
          StatusCallback( cReadyTxt );

          // Tables_anlegen; // Tabellen werden angelegt
          CreateTables( StatusCallback );

        except
          on E : Exception do
            begin
              if FileExists( DBPath )
              then
                DeleteFile( DBPath );

              // StatusMeldung (Callback-Methode aufrufen)
              StatusCallback( cFailureText );

              raise;
            end;
        end;

      finally
        Screen.Cursor := crDefault;
      end;
    end;
Und damit ist in
Delphi-Quellcode:
TForm3.SpeedButton9Click
auf einen Blick klar, was da passiert -> Es wird eine Datenbank angelegt (Documentation by Code). Vorher musste man sich erst durch den Quellcode wühlen, um das festzustellen.

Lieber Sir Rufo, der SourceCode stammt fast 1:1 von Andreas Kosch (Datenbankentwicklung mit Interbase - S.338-339). Bisher hatte ich an dem Buch wenig auszusetzten.
Dennoch vielen Dank für Deine Anregungen.
Meine eigentliche Frage ist aber immer noch nicht beantwortet worden !

Sir Rufo 18. Dez 2013 10:36

AW: Interbase SQL-Dialect 1/3 - Problem
 
@wendelin

Du hast auch immer noch nicht das Skript gezeigt, was da ausgeführt werden soll.
Wie sollen wir das also beantworten können?

Vorbeikommen und auf deinen Bildschirm schauen?

Hoffentlich hast du genug zu trinken da :cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:55 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