Announcement

Collapse
No announcement yet.

AutoInt bei InterBase unter Delphi 5

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • AutoInt bei InterBase unter Delphi 5

    hallo,

    früher funktionierte es mit einem generator und einen trigger bei einer query-komponente wunderbar. bei TIBQuery nicht mehr, kommt eine fehler-meldung - feld ... darf nicht null sein (primärindex).
    kennt jemand eine lösung für TIBQuery?

    danke, psp

  • #2
    Hallo,

    auf welchem Weg wird mit <b>TIBQuery</b> ein neuer Datensatz in der Tabelle abgelegt, bei dem ein InterBase-Generator den neuen Wert (Primärschlüssel?) generiert

    Comment


    • #3
      hallo andreas,

      ich hänge einfach mit append einen neuen datensatz an. ich denke, daß jetzt bei append oder insert erst das indexfeld kontrolliert wird, bevor der trigger einen neuen wert vom generator holt. und dadurch kommt diese fehlermeldung, indexfeld darf nicht null sein. es gibt ja die möglichkeit, über store procedure gleich nach append einen wert vom trigger zu holen..., aber wenn der anwender dann diesen datensatz verwirft, ist die zahl auch weg. es geht auch, wenn ich das indexfeld mit z.b. -1 belege, dann funktioniert es. aber nach post wird das feld auch nicht aktuallisiert, ich muß IBQuery schließen und wieder öffnen, dann ist aber der zeiger zum datensatz nicht mehr da.

      psp-bernd tausche

      Comment


      • #4
        Am besten holst du dir die nummer des generators mit hilfe einer stored procedure. das macht du am besten im beforepost der query und zwar nur dann, wenn das indexfeld nicht initialisiert ist. dann speichert die query den richtigen wert und dürfte keine probleme mehr haben. du kannst zur sicherheit noch einen beforeinsert-trigger in die datenbank aufnehmen, der das indexfeld initialisiert, wenn es noch nicht initialisiert sein sollte

        Comment


        • #5
          Hallo Bernd,

          dieses Thema war ja noch offen - allerdings ist meine Frage vom 14. Oktober immer noch nicht beantwortet. Ich hätte gern gewusst, wie über <b>TIBQuery.Append</b> ein Datensatz angelegt werden kann (unabhängig vom Primärschlüsselwert). Bislag war ich immer der Aufassung, das TIBQuery als einzelne Komponente nur Read-Only ist (Zitat aus der Hilfe: <i>IBQuery-Komponenten stellen eine Nur-Lesen-Datenmenge bereit und fügen sich sehr gut in die Client/Server-Umgebung von InterBase ein. </i>)! Der folgende Aufruf provoziert also in jedem Fall eine Exception:

          <pre>
          procedure TForm1.Button1Click(Sender: TObject);
          begin
          IBQuery1.Append;
          IBQuery1PLZ.Value := '99999';
          IBQuery1ORT.Value := 'Test';
          IBQuery1.Post;
          end;
          </pre>

          Normalerweise soll eine neue Anwendung auf <b>TIBDataset</b> aufgebaut werden - und dort kann im Objektinspektor über die Eigenschaften <b>InsertSQL</b>, <b>ModifySQL</b> und <b>DeleteSQL</b> für jede Aktion die exakt benötigte SQL-Anweisung definert werden. Und wenn der InterBase den Generatorwert zuordnet, wird in der InsertSQL-Anweisung diese Spalte weggelassen!

          Eine Beschreibung, in welcher Situation welche <b>IBX-Komponente</b> am sinnvollsten ist, findet sich in der Hilfedatei <b>IBX.HLP</b> auf der Seite <i>Grundlagen zu InterBase Express</i>

          Comment


          • #6
            hallo andreas,
            also, ich habe ein IBDatabbase, IBTransaction, IBQuery und dazu IBUpdateSQL. functioniert alles wunderbar. ohne primärindex kann ich datensätze anfügen, löschen, ändern... mit primärindex feld ID bei mir kann ich keine datensätze anfügen... fehlermeldung -> Feld ID muß einen Wert haben... den trigger habe ich auch als Before Insert definiert.

            psp-bern

            Comment


            • #7
              Hallo Bernd,

              aha - ich hatte ja nicht ohne Grund so formuliert: <i>"Bislag war ich immer der Aufassung, das TIBQuery als einzelne Komponente nur Read-Only ist"</i> (Betonung auf <b>einzelne</b> Komponente). Somit ist mit Deiner Konfiguration nicht TIBQuery, sondern <B>TIBUpdateSQL</b> für das Einfügen des Datensatzes zuständig. Wenn der Primärschlüsselwert automatisch vom <b>Trigger</b> in der Datenbank gesetzt wird, darf dieses Feld <b>nicht</b> mit in die INSERT-Anweisung aufgenommen werden. Es muß also die <b>InsertSQL</b>-Eigenschaft von TIBUpdateSQL geändert werden

              Comment


              • #8
                hallo andreas,
                danke, habe ich wie folgt geändert<br>
                insert into T_ZIMMERTYP<br>
                (GEN, ZINAME)<br>
                values<br>
                (:GEN, :ZINAME)<br>
                mein feld ID habe ich aus der anweisung gelöscht. es kommt aber immer noch die fehlermeldung... Fels ID muß einen wert haben.

                psp-bern

                Comment


                • #9
                  Hallo Bernd,

                  wurden <b>persistente TFields</b> für die TIBQuery-Instanz angelegt und ist dort auch die Eigenschaft <b>Required</b> für die ID-Spalte auf FALSE gesetzt? Ein funktionstüchtiges Beispiel, bei dem die Fehlermeldung nicht erscheint, füge ich bei (nur visuelle Konfiguration im Objektinspektor - kein manuell eingetragener Sourcecode):

                  <b>Datenbank</b>:
                  <pre>
                  CREATE TABLE TABLE1 (
                  ID INTEGER NOT NULL PRIMARY KEY,
                  USERNAME CHAR(8) NOT NULL,
                  LOGINTIME DATE NOT NULL);

                  CREATE TRIGGER BEFORE_INSERT FOR TABLE1 BEFORE INSERT POSITION 0 AS
                  BEGIN
                  IF(NEW.id IS NULL) THEN
                  NEW.id = GEN_ID(table1_gen,1);
                  END
                  </pre>

                  <b>Beispielprojek</b>: TIBDatabase + TIBTransaction + TIBQuery + TIBUpdateSQL

                  <pre>
                  object Form1: TForm1
                  Left = 192
                  Top = 107
                  Width = 696
                  Height = 480
                  Caption = 'Form1'
                  Color = clBtnFace
                  Font.Charset = DEFAULT_CHARSET
                  Font.Color = clWindowText
                  Font.Height = -11
                  Font.Name = 'MS Sans Serif'
                  Font.Style = []
                  OldCreateOrder = False
                  PixelsPerInch = 96
                  TextHeight = 13
                  object DBGrid1: TDBGrid
                  Left = 168
                  Top = 56
                  Width = 320
                  Height = 120
                  DataSource = DataSource1
                  TabOrder = 0
                  TitleFont.Charset = DEFAULT_CHARSET
                  TitleFont.Color = clWindowText
                  TitleFont.Height = -11
                  TitleFont.Name = 'MS Sans Serif'
                  TitleFont.Style = []
                  end
                  object DBNavigator1: TDBNavigator
                  Left = 168
                  Top = 24
                  Width = 240
                  Height = 25
                  DataSource = DataSource1
                  TabOrder = 1
                  end
                  object IBDatabase1: TIBDatabase
                  Connected = True
                  DatabaseName = 'C:\Database\IB\Smudf.gdb'
                  Params.Strings = (
                  'user_name=sysdba'
                  'password=masterkey'
                  'lc_ctype=WIN1252')
                  LoginPrompt = False
                  DefaultTransaction = IBTransaction1
                  IdleTimer = 0
                  SQLDialect = 1
                  TraceFlags = []
                  Left = 16
                  Top = 16
                  end
                  object IBQuery1: TIBQuery
                  Database = IBDatabase1
                  Transaction = IBTransaction1
                  Active = True
                  CachedUpdates = False
                  SQL.Strings = (
                  'select * from TABLE1')
                  UpdateObject = IBUpdateSQL1
                  Left = 56
                  Top = 16
                  object IBQuery1ID: TIntegerField
                  AutoGenerateValue = arDefault
                  FieldName = 'ID'
                  ProviderFlags = [pfInWhere]
                  end
                  object IBQuery1USERNAME: TIBStringField
                  FieldName = 'USERNAME'
                  Required = True
                  Size = 8
                  end
                  object IBQuery1LOGINTIME: TDateTimeField
                  FieldName = 'LOGINTIME'
                  Required = True
                  end
                  end
                  object IBTransaction1: TIBTransaction
                  Active = True
                  DefaultDatabase = IBDatabase1
                  Left = 16
                  Top = 48
                  end
                  object DataSource1: TDataSource
                  DataSet = IBQuery1
                  Left = 96
                  Top = 16
                  end
                  object IBUpdateSQL1: TIBUpdateSQL
                  RefreshSQL.Strings = (
                  'Select '
                  ' ID,'
                  ' USERNAME,'
                  ' LOGINTIME'
                  'from TABLE1 '
                  'where'
                  ' ID = :ID')
                  ModifySQL.Strings = (
                  'update TABLE1'
                  'set'
                  ' USERNAME = :USERNAME,'
                  ' LOGINTIME = :LOGINTIME'
                  'where'
                  ' ID = :OLD_ID')
                  InsertSQL.Strings = (
                  'insert into TABLE1'
                  ' (USERNAME, LOGINTIME)'
                  'values'
                  ' (:USERNAME, :LOGINTIME)')
                  DeleteSQL.Strings = (
                  'delete from TABLE1'
                  'where'
                  ' ID = :OLD_ID')
                  Left = 56
                  Top = 48
                  end
                  end
                  </pre&gt

                  Comment


                  • #10
                    hallo andreas,
                    funktioniert, und ich habe gesehen, dort kann man auch die eigenschaft AutoGenerateValue einstellen, dann funktioniert es auch.
                    war eine hilfreicher hinweis, danke, aber leider komme ich nicht an den wert, er wird nicht aktuallisiert. refresh hilft nicht...

                    psp-bern

                    Comment


                    • #11
                      Hallo Bernd,

                      die <b>TIBQuery</b>-Komponente ist das Kompatibilitätsobjekt für <b>TQuery</b>. Und bei TQuery verursachte jeder Aufruf von <b>Refresh</b> eine Exception - also ist das Verhalten von TIBQuery "plausibel". Bislang sorgt nur das erneute Ausführen von TQuery dazu, das die neuen Daten aus der Datenbank angezeigt werden.

                      Mit <b>TIBDataset</b> sollte das direkte Aktualisieren der vom Trigger gesetzten Werte funktionieren, ich werden mir die Sache mit TIBQuery noch einmal anschauen

                      Comment

                      Working...
                      X