Announcement

Collapse
No announcement yet.

TIBDataSet und GeneratorField

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

  • TIBDataSet und GeneratorField

    Hallo,

    Ich habe folgendes Problem: In einem Grid soll der 1. Datensatz für eine leere IB-Tabelle erfaßt werden. Das Grid ist mit einer DataSource, deren Eigenschaft AutoEdit auf true steht, verbunden. In einer TIBDataSet-Komponente wurde ein Generator in das Property GeneratorField mittels des Editors eingetragen (Option: Beim Speichern). Wenn ich nun im Grid den 1. Datensatz speichern möchte, kommt die Fehlermeldung, daß das Primary-Key-Field einen Wert braucht, also, der Generator wurde nicht ausgelöst. Den Fehler habe ich schnell gefunden. TIBDataSet löst für den 1. Datensatz kein Ereignis OnNewRecord aus. Infolgedessen steht State auf dsEdit. In der Datei IBCustomDataSet.Pas kann aber eine Auslösung des Generators nur dann stattfinden, wenn State auf dsInsert steht. In der entsprechenden IF-Abfrage wird dann auch "Required" auf false gesetzt. Wie kriege ich das hin, daß der Generator doch für das Speichern des allerersten Datensatzes ausgelöst wird?

  • #2
    Hallo,

    in jedem Fall sollte sich das Problem lösen lassen, wenn für die Primärschlüsselspalte der TIBDataSet-Komponente eine persistente TField-Instanz angelegt wird, für die man im Objektinspektor die Eigenschaft <b>Required</b> selbst permanent auf False setzt

    Comment


    • #3
      Hallo Herr Kosch,

      wenn ich das Property Required := false setze, stürzt das Programm mit einer EAccessViolation-Exception ab. Dies passiert in IBCustomDataSet in der Zeile 2014 bei der Anweisung „ReadRecordCache“, wenn er bis zum letzten Feld der Tabelle angekommen ist. Meines Erachtens liegt der eigentliche Fehler darin, daß TIBDataSet, nicht wie TIBQuery und TIBTable beim AutoEdit, den 1. Datensatz einer Tabelle nicht als NewRecord, also State = dsInsert, betrachtet, sondern State in den Modus dsEdit versetzt. Dadurch werden die Bedingungen zum Auslösen des Generators in IBCustomDataSet in Zeile 3784 „ if State = dsInsert then if FGeneratorField.ApplyEvent = gamOnPost then FGeneratorField.Apply;“ nicht erfüllt. Der nachfolgende Befehl „inherited Post;“ wird ohne Aufruf des Generators ausgeführt und es kommt entweder zum EAccessViolation oder, wenn Tfield.Required = true ist, zur Fehlermeldung „Feld ID braucht einen Wert“. Dadurch, daß der 1. einzugebende Datensatz im Grid als dsEdit und nicht als dsInsert erkannt wird, hilft auch der Einsatz einer StoredProcedure unter OnNewRecord nichts. Was mache ich mit TIBDataSet falsch

      Comment


      • #4
        Hallo,

        ich kann das Problem nicht reproduzieren (Delphi 6.01; IBX 6.01). Bei dem folgenden Testprogramm kann ich im TDBGrid in einer leeren Tabelle auch dann einen Datensatz anlegen, wenn ich die AutoEdit-Umschaltung nutze. Der Generatorwert wird <b>On Post</b> angefordert:
        <pre>
        object Form1: TForm1
        Left = 286
        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 = 24
        Top = 104
        Width = 569
        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 = 24
        Top = 80
        Width = 560
        Height = 25
        DataSource = DataSource1
        TabOrder = 1
        end
        object IBDatabase1: TIBDatabase
        Connected = True
        DatabaseName = 'C:\Database\IB6\NEU6D3.GDB'
        Params.Strings = (
        'user_name=SYSDBA'
        'password=masterkey'
        'lc_ctype=ISO8859_1')
        LoginPrompt = False
        DefaultTransaction = IBTransaction1
        IdleTimer = 0
        SQLDialect = 3
        TraceFlags = []
        Left = 24
        Top = 16
        end
        object IBTransaction1: TIBTransaction
        Active = True
        DefaultDatabase = IBDatabase1
        AutoStopAction = saNone
        Left = 24
        Top = 48
        end
        object IBDataSet1: TIBDataSet
        Database = IBDatabase1
        Transaction = IBTransaction1
        BufferChunks = 1000
        CachedUpdates = False
        DeleteSQL.Strings = (
        'delete from JUST'
        'where'
        ' ID = :OLD_ID')
        InsertSQL.Strings = (
        'insert into JUST'
        ' (ID, C1, C2, C3, C4)'
        'values'
        ' (:ID, :C1, :C2, :C3, :C4)')
        RefreshSQL.Strings = (
        'Select '
        ' ID,'
        ' C1,'
        ' C2,'
        ' C3,'
        ' C4'
        'from JUST '
        'where'
        ' ID = :ID')
        SelectSQL.Strings = (
        'select ID, C1, C2, C3, C4 from JUST')
        ModifySQL.Strings = (
        'update JUST'
        'set'
        ' ID = :ID,'
        ' C1 = :C1,'
        ' C2 = :C2,'
        ' C3 = :C3,'
        ' C4 = :C4'
        'where'
        ' ID = :OLD_ID')
        GeneratorField.Field = 'ID'
        GeneratorField.Generator = 'OS_GEN'
        GeneratorField.ApplyEvent = gamOnPost
        Active = True
        Left = 64
        Top = 16
        object IBDataSet1ID: TIntegerField
        FieldName = 'ID'
        Origin = 'JUST.ID'
        Required = True
        end
        object IBDataSet1C1: TIBBCDField
        FieldName = 'C1'
        Origin = 'JUST.C1'
        Precision = 18
        Size = 2
        end
        object IBDataSet1C2: TLargeintField
        FieldName = 'C2'
        Origin = 'JUST.C2'
        end
        object IBDataSet1C3: TLargeintField
        FieldName = 'C3'
        Origin = 'JUST.C3'
        end
        object IBDataSet1C4: TIBBCDField
        FieldName = 'C4'
        Origin = 'JUST.C4'
        Precision = 18
        Size = 2
        end
        end
        object DataSource1: TDataSource
        DataSet = IBDataSet1
        Left = 104
        Top = 16
        end
        </pre&gt

        Comment


        • #5
          Hallo Herr Kosch,

          ich arbeite mit Delphi 5 (UpdatePatch 2, IBX 4.62 und das Grid eine Wool2Woll-InfoPower 2000-Komponente vom TwwDBGrid. Vielleicht liegt es daran. Ich werde jedem Ihr Beispiel mit einem TDBGrid ausprobieren und melde mich dann wieder

          Comment


          • #6
            Hallo Herr Kosch,

            das Problem ist gelöst! Schuld war eine Event-Procedure von TwwDBGrid (InfoPower), die noch vor dem Generator-Event ausgelöst wurde. Da in dieser TwwDBGrid-Event-Procedure Datensätze gesucht und deren Werte berechnet wurden, konnte der Satz ohne Primary-Key nicht gespeichert werden. Vielen Dank für Ihre Mühe

            Comment

            Working...
            X