Announcement

Collapse
No announcement yet.

InterBase ahoi! = NULL oder doch NOT NULL ???

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

  • InterBase ahoi! = NULL oder doch NOT NULL ???

    Hallo Andreas Kosch,

    Ich habe Deinen nüchterner Artikel über Delphi6 (in der Entwickler-Zeitschrift) mit großer Interesse gelesen...Überraschend erfuhr ich aber dort auch, dass Du gerade an einem Buch über Interbase 6 arbeitest.

    Nun da haben wir hier drei „kleine Problemchen“, die Du vielleicht in Deinem Buch behandeln solltest?

    So oder so ich würde mich freuen, wenn Du etwas dazu sagen würdest...

    Wir haben folgende Probleme mit Interbase 6.0:

    1. Wenn ein Tabellenfeld als VARCHAR NOT NULL definiert ist,
    wie ist es möglich, dass dieses Feld editiert, geleert, und gespeichert werden kann (In der BDE kannst Du es ganz schnell erzeugen)? Ich kam ganz zufällig drauf, da ich gerade eine BDE- Fehlerbehandlung programmieren wollte, da waren aber keine Fehler da...

    2. Warum kann IB6 nicht mehr als 114 Generatoren bilden (danach ist die Datenbank korrupt)

    3. Wie kann nach einem Datenbankfeld sortiert werden (ORDER BY), ohne dass die groß/klein- Schreibung berücksichtigt wird?

    Viele Grüße von und noch viel, viel Erfolg wünscht Dir

    Paul Jr.

    (http://Delphi-Forum.de)

  • #2
    Hallo Paul,

    zu 1.) <b>not null</b> heißt, das das Datenfeld keinen Inhalt hat, ein leerer String ist aber ein Inhalt/Wert. Einfacher Test:

    Tabelle mit zwei Spalten (ID integer, Name varchar(30) not null)

    <pre>begin
    query1.sql.add('insert into TestTable (ID) values (100)');
    query1.execsql;
    end;
    </pre>

    Nach diesem Code bekommst Du Deine Fehlermeldung!

    2.) bisher noch keine Erfahrungen damit gesammelt

    3.) separate Spalte anlegen in der die Strings in Großbuchstaben gespeichert werden. Am besten die Spalte durch einen Before Insert-Trigger bzw. Before UpDate-Trigger automatisch füllen lassen

    Tschüß

    Torste

    Comment


    • #3
      Hallo Torsten,

      (...)
      zu 1.) not null heißt, das das Datenfeld keinen Inhalt hat, ein leerer String ist aber ein Inhalt/Wert.
      (...)

      tja...das brauche ich nicht mall zu prüfen, da gewiss in der BDE wird bei editieren einen Leerstring generiert...keine Frage, da hast Du Recht. Mir ist aber Teilweise bei anlegen von neuen Datensätzen dieses Phänomen gelungen was mich echt sprachlos gemacht hat (von Delphi her), aber das wollte ich vorerst nicht reinschreiben...(so wie so kommt die Formulierung in meiner erster Frage von meinem Freund darum habe ich es Inhaltlich nicht so ganz genau nachgeprüft...sorry...). Also vergessen wir vorerst Leerstrings...und das ist mir mit einfachen (TTable) Append und CheckBrowseMode gelungen...glaube mir...

      (...)
      3.) separate Spalte anlegen in der die Strings in Großbuchstaben gespeichert werden. Am besten die Spalte durch einen Before Insert-Trigger bzw. Before UpDate-Trigger automatisch füllen lassen
      (...)

      Na ja Torsten...Trigger sind glaube nicht unbedingt dazu da...Vor allem bei 130 Tabellen mit vielen, vielen Spalten, das kommt leider nicht in Frage...aber natürlich bei kleineren Anwendungen wäre das eine interessante alternative...Das scheint ein echtes Problem zu sein, das wir z.B. bei Oracle nicht haben...

      Ich danke Dir jedoch für Deine Bemühungen...

      Gruß

      Paul Jr

      Comment


      • #4
        Hallo Paul,

        zu 1.) mit TTable hast Du Dir die "allerschnellste" Zugriffskomponente ausgesucht. Wenn Du auch einen Leerstring als ungültig definieren möchtest, dann erzeuge eine eigene Domain mit entsprechender Check-Anweisung
        (z.B. <b>create domain MyName as Varchar(30) check (value <> '')</b>)

        zu 3.) Der Zugriff auf IB über die BDE ist an sich schon eine Performance-Bremse, deswegen sollte man dann wenigstens im DB-Design drauf achten, nicht noch zusätzliche "Bremsen" einzubauen. Alternativ zu eiener zusätzlichen Spalte kann man das Select so gestalten <b> select Name, Upper(Name) from TestTable order by 2</b>

        Tschüß

        Torste

        Comment


        • #5
          Hallo Torsten,

          (...)
          >>mit TTable hast Du Dir die "allerschnellste" Zugriffskomponente ausgesucht.

          (...)

          he, he...lass gut sein ;-)), es seitdem Du weißt wie ich mit Query(Live) bei Append und anschließend Post die ID rausholen kann(?) (Generator + Trigger(before insert), dass wäre wirklich SUPPER.

          Das hier von Dir...

          create domain MyName as Varchar(30) check (value <> '')

          ist wirklich gut...Danke...nun so mache ich es, damit bin ich gut bedient und das mit dem Append (habe jetzt nachgeprüft) entsteht tatsächlich, wenn jemand das betreffende Feld direkt im Programm kurz Editiert (ich bin, glaube ich, langsam Urlaubs reif...)...also die Sache hat sich dank Dir erledigt...

          ___________________________________

          (...)
          select Name, Upper(Name) from TestTable order by 2
          (...)

          Klar, das ist schon viel flexibler (mir auch bekannt) als vorher mit diesen Spalten, besser wäre natürlich hier dieser Konstrukt:

          <b>SELECT TestTable.*, UPPER(NAME) AS SORTFIELD2 FROM TestTable ORDER BY 2</b>

          Es kann im Query-Felder-Editor das Feld SORTFIELD2 ausgeblendet werden (visible = FALSE)...(ich sortiere hier mit DBGrid)

          Jedoch wandelt UPPER die Umlaute ä, ö, ü nicht, sowie das Ö, Ü erscheint nach der Sortierung hinter dem Z(!) (LANGDRIVER='WEurope' ANSI)

          Dein alternativer Vorschlag ist auch als solcher sehr langsam, vielleicht hast Du noch irgendwelche Ideen?

          _________________________

          Da bleibt natürlich noch die Sache mit den Generatoren...bis jetzt mache ich es so, dass ich mit einem Generator mehrere kleinere Tabellen bediene...(unter InterBase 5.6 hatte ich das Problem nicht)

          Viele Grüße und Danke für Deine Hilfe

          Paul Jr

          Comment


          • #6
            Hallo Paul,

            (...) Jedoch wandelt UPPER die Umlaute ä, ö, ü nicht, sowie das Ö, Ü erscheint nach der Sortierung hinter dem Z(!) (LANGDRIVER='WEurope' ANSI) (...)

            wie wäre es mit:

            SET SQL DIALECT 3;<br>

            SET NAMES ISO8859_1;<br>
            CREATE DATABASE 'D:\test.gdb'<br>
            USER 'SYSDBA' PASSWORD 'xyz'<br>
            PAGE_SIZE 4096<br>
            DEFAULT CHARACTER SET ISO8859_1;<br>

            /* Domain dazu mit COLLATE DE_DE */<br>
            CREATE DOMAIN TEXT_C12 AS VARCHAR(12)<br>
            COLLATE DE_DE;<br>

            /* und sortiert mit Umlauten<br>
            select kunden.Name, Upper(kunden.Name) from kunden order by 2<br>

            bei mir klappt das jedenfalls - auch mit Umlauten.

            Matthia

            Comment


            • #7
              Hallo Paul,

              ich füge neue Datensätze in meinen Programmen fast ausschließlich über StoredProc's ein und lasse mir als Rückgabeparameter den verwendeten Generatorwert mitteilen. Darüber hinaus prüfe ich in einem Trigger ob der Primary Key not null ist, wenn der Wert null ist hole ich mir einen neuen Generatorwert ab. Damit stelle ich sicher, dass automatisch ein gültiger Primary Key vorhanden ist, auch wenn mit Datenbank-Tools direkt an den Tabellen "rumgespielt" wird.

              Das mit der Anzahl der Generatoren werde ich jetzt gleich mal testen und dann Bescheid geben.

              Tschüß

              Torste

              Comment


              • #8
                Hallo Paul,

                also ich habe auch mit mehr als 114 Generatoren keine Probleme feststellen können.

                Tschüß

                Torste

                Comment


                • #9
                  <b>Hallo Matthias und Torsten,</b>

                  <b>also, spätestens jetzt muss ich zugeben, dass ich von Euch und vor allem von Eurem Wissen echt begeistert bin ;-) </b>

                  Ehrlich gesagt, habe ich nicht gedacht, dass man mir hier so präzise und schnell helfen kann...


                  _________________

                  Matthias..., Dir danke ich für Dein Tipp...werde es morgen ausprobieren und hier Bescheid sagen

                  _________________

                  Torsten..., danke, dass Du die Generatoren nachgeprüft hast. Was bei Dir klappt müsste auch bei uns klappen. Vielleicht haben wir irgendwo (in dem SQL- Script) ein Fehler gemacht...das werde ich auch noch einmal prüfen. Darüber hinaus würde ich mich echt freuen, wenn Du mir hier verständlich gezeigt hättest (ein Beispiel vielleicht), wie Du im Detail bei einfügen von neuen Datensätze vorgehst..., dass wäre wirklich eine große Hilfe für mich..., und dabei könnte ich wirklich was neues lernen...Zeige bitte die StoredProc's, Trigger usw....

                  Viele Grüße an Euch beiden...und noch einmal danke...

                  Paul Jr

                  Comment


                  • #10
                    Hallo Paul,

                    hier mal der SQL-Code:

                    <b>Tabelle:</b>
                    <pre>
                    CREATE TABLE ADRESSEN (
                    POSTLEITZAHL VARCHAR(5),
                    ORT VARCHAR(30),
                    STRASSE VARCHAR(30),
                    HAUSNUMMER VARCHAR(7),
                    ID INTEGER);
                    CREATE UNIQUE INDEX ADRESSEN_INDEX ON ADRESSEN (ID);
                    CREATE UNIQUE INDEX ADRESSEN_KOMPLETT ON ADRESSEN (POSTLEITZAHL, ORT, STRASSE, HAUSNUMMER);
                    </pre>

                    <b>Procedure:</b>
                    <Pre>
                    CREATE PROCEDURE INSERT_ADRESSEN (
                    PLZ VARCHAR(5),
                    ORT VARCHAR(30),
                    STR VARCHAR(30),
                    NR VARCHAR(7))
                    RETURNS (
                    ADRESS_ID INTEGER)
                    AS
                    begin
                    adress_id = gen_id(adressen_id, 1);
                    insert into adressen (ID, postleitzahl, ort, strasse, hausnummer)
                    values (:adress_id, lz, rt, :str, :nr);
                    when sqlcode -803 do
                    select ID from adressen
                    where (postleitzahl = lz) and (ORT = :ORT)
                    and (STRASSE = :STR) and (HAUSNUMMER = :NR)
                    into :adress_id;
                    suspend;
                    end
                    </pre>
                    <b> ...when sqlcode -803...</b> "vermeidet" (genauer gesagt fängt die Fehlermeldung "violation of PRIMARY or UNIQUE KEY constraint ..." ab) doppelte Datensätze und liefert statt dessen die ID des bereits vorhandenen Datensatzes

                    <b>Trigger:</b>
                    <pre>
                    CREATE TRIGGER TABLE_ADRESSEN_SET_ID FOR ADRESSEN
                    ACTIVE BEFORE INSERT POSITION 0
                    as
                    begin
                    if (new.id is null) then new.id = gen_id(adressen_id, 1);
                    end
                    </pre>

                    Zu den Generatoren: versuch doch mal ein Backup der DB und anschließend ein Restore.<p>
                    Umlaute in den Namen für die Generatoren werden doch hoffentlich nicht verwendet? Damit soll der IB-Server nämlich so seine Probleme haben.

                    Tschüß

                    Torste

                    Comment


                    • #11
                      Hallo,

                      es gelten beim InterBase 6 die folgenden Beschränkungen für Generatoren:
                      <pre>
                      Version Page-Size Maximale Generator-ID
                      6.x 1 kByte 124 <br>
                      6.x 2 kByte 257<br>
                      6.x 4 kByte 508<br>
                      6.x 8 kByte 1020<br>
                      </pre&gt

                      Comment


                      • #12
                        Hallo an Alle,

                        da bin ich hier zum letzten mal....

                        Eure Tipps waren sehr gut und alles klappt jetzt prima bei mir. Ich habe hier 3 Fragen gestellt. Erste Frage war mein Fehler. Bezüglich beiden anderen Fragen (die in so weit berechtigt waren) habe ich hier Hilfe gefunden...Danke.

                        Darüber hinaus hat mir Torsten noch zusätzlich gezeigt wie man ID bei einfügen von Datensätzen per Stored-Procedure herausholen kann. Da ich auch sehr gerne auf der Datenbank-Ebene manche Sachen programmiere war diese Tipp von Ihm der wichtigste der ich hier ganz zufällig bekommen habe. Darum kann ich jetzt sagen:

                        InteBase ahoi! - doch NOT NULL

                        Gruß

                        Paul Jr.

                        P.S.

                        Verzeih meine Schreibfehler, aber bin nicht in Deutschland geboren..., sondern in Polen...und da habe ich manchmal schon meine Probleme.

                        Comment

                        Working...
                        X