Announcement

Collapse
No announcement yet.

Übertrag von Nullwerten in eine Tabelle mittels parametrisierter Query-Abfrage

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

  • Übertrag von Nullwerten in eine Tabelle mittels parametrisierter Query-Abfrage

    Hallo,

    Ich habe eine Tabelle „Customer.db“ mit den Feldern KundenNr, KundenName, KundeSeit und möchte mittels parametrisierter Query-Abfrage Daten in die Tabelle einfügen, wobei auch Nullwerte zulässig sein sollen.

    SQL.String:
    <PRE>INSERT INTO „Customer.db“
    VALUES (:KundenNr, :Kundenname, :KundeSeit)</PRE>

    Einfügen des neuen Datensatzes in „Customer.db“ mit folgenden Anweisungen:

    <PRE>with Query1 do begin
    Close;

    if (Edit1.Text <> '') then
    ParamByName('KundenNr').AsInteger := IntToStr(Edit1.Text)
    else
    ParamByName('KundenNr').Value := Null; { Fehlermeldung! }

    ParamByName('KundenName').AsString := Edit2.Text;

    if (Edit3.Text <> '') then
    ParamByName('KundeSeit').AsDateTime := StrToDate(Edit3.Text)
    else
    ParamByName('KundeSeit').Value := Null; { Fehlermeldung! }

    ExecSQL;
    end;</PRE>

    Wurde z. B. in Edit1 keine Kundennummer eingegeben, dann wird die Übernahme der Eingabedaten in die Tabelle mit der Fehlermeldung "Typ für Feld 'KundenNr' ist unbekannt." Abgebrochen. Dieselbe Fehlermeldung erhalte ich, wenn ich programmiere:

    … ParamByName('KundenNr').SetData(nil);

    Lösungen wie
    … ParamByName('KundenNr').AsString := '';
    … ParamByName('KundenNr').Text := '';
    führen zur Meldung "Keine Übereinstimmung der Typen im Ausdruck".

    Wie lassen sich aber dann Nullwerte via parametrisierter Query-Abfrage in eine Tabelle einfügen?

    Der direkte, aber nicht gangbare Weg, über
    … Table.FieldByName('KundenNr').AsVariant := Null;
    würde funktionieren. TParam dagegen hat aber keine Eigenschaft AsVariant.

    Besten Dank für jeglichen Hinweis, der mich einer Lösung näher bringt.

  • #2
    Hallo Wolfgang,

    ...ParamByName('Feld').Clear;

    Gruß

    Torste

    Comment


    • #3
      Hallo Torsten,

      vielen Dank für die schnelle antwort. Leider führt aber auch die Anweisung

      ... ParamByName('KundenNr').Clear;

      zur Meldung "Typ für Feld 'KundenNr' ist unbekannt.

      Im Übrigen sollte ich noch nachtragen, dass ich mit D5 Prof. arbeite.

      Viele Grüße Wolfgan

      Comment


      • #4
        Hallo Wolfgang,

        welchen Typ hat das Feld KundNr?

        Sprechen wir von zulässigen NULL-Werten, oder von zulässigen 0-Werten?

        wenn es int ist:
        <PRE>
        int kdnr;
        if (Edit1->Text.IsEmpty())
        { // Textfeld leer, KundNr = 0
        kdnr = 0;
        }
        else
        { // Textfeld nicht leer, in int wandeln, gibt -1 zurück, wenn Zahl nicht konvertiert werden kann
        kdnr = Edit1->Text.ToIntDef(-1);
        }
        if (kdnr == -1)
        // Fehlerhafte Eingabe im Edit...
        else
        ParamByName("KundenNr")->AsInteger = kdnr;
        </PRE>

        Wenn es ein char ist, was passiert, wenn Du den Parameter für KdNr gar nicht erst setzt (vorher alle Parameterwerte löschen...)

        Grüße Joche

        Comment


        • #5
          Hallo Jochen,

          in meiner vorgestellten (Beispiel-) Anwendung soll es möglich sein (egal ob sinnvoll oder nicht), dass der Anwender KEINE Kundennummer eingibt und damit das INTEGER-Feld KundenNr der Tabelle customer.db leer bleibt. Da ich aber in der SQL-Anweisung einen Parameter :KundenNr "fest installiert" habe, dachte ich, muß ich bei Nichteingabe einer Kunden-Nummer durch den Anwender den Parameterwert NULL übergeben. Übergebe ich im Falle der Nichteingabe überhaupt keine Parameterwert (so verstehe ich Deinen vorschlag im letzten Absatz), dann erscheint die Meldung "Typ für Feld 'KundenNr' ist unbekannt".

          Dem Feld KundenNr möchte ich im Falle der Nichteingabe aus verschiedenen Gründen keinen Integer-Wert 0 zuweisen. (Nach demselben Prinzip müßte dann ein Datumsfeld mit dem 01.01.1899 = Real-Wert 0 belegt werden und das ist doch wirklich unschön.)

          Viele Grüße Wolfgang

          Comment


          • #6
            Hallo Wolfgang,

            sieht so aus, als hättest Du vergessen, im Params-Editor die Feldtypen zu spezifizieren. Daher die Fehlermeldung Typ für Feld unbekannt. Nutzt aber sowieso nix, da bei dieser Vorgehensweise NULL-Werte automatisch zu 0-Werten konvertiert werden. Einzige Möglichkeit, die mir so einfällt, ist das SQL zu Laufzeit zu ändern:
            <PRE>
            INSERT INTO Kunden.db
            (Name)
            VALUES (:Kundenname)
            </PRE>
            Nur hierbei erhalten Kundennummer und KundeSeit NULL-Werte.

            Grüße Joche

            Comment


            • #7
              Hallo, <br><br>

              Es ist möglich NULL-Werte zu übergeben, nur muss dazu, wie von Jochen genannt, der Feldtyp des Parameter gesetzt werden. (Eigenschaft Params der Query). <br><br>
              Query.Params[0].DataTyp und Query.Params[0].Value.Typ (Diese stehen standardmäßig auf unassigned!)
              <br><br>
              Gruß<br>
              M.Pannie

              Comment


              • #8
                Besten Dank für Euere Hinweise. Ich werde Sie ausprobieren und darf mich ggf. zurückmelden. - Tatsächlich habe ich die Feldtypen nicht spezifiziert.

                Viele Grüße Wolfgan

                Comment


                • #9
                  Also, ich hab's ausprobiert: Wenn ich die Felder in der Parameterliste drin habe und NULL-Werte übergebe, werden diese in 0 gewandelt. Ich gehe mal davon aus, daß die verwendete DB Paradox ist...

                  Grüße Joche

                  Comment


                  • #10
                    Die Eigenschaft Query.Params[0].Value.Typ muss NULL sein! So kann, wenn ein Wert vorhanden ist dieser übergeben werden ansonsten einfach nichts übergeben, dann wird automatisch NULL genommen.<br>
                    Bsp.:<br><br>
                    if Wert <= 0 then<br>
                    begin<br>
                    //Mache nichts<br>
                    end else<br>
                    begin<br>
                    Query.Params[0].AsInteger := Wert;<br>
                    end; <br><br>
                    Allerdings verwende ich die IBX-Komponenten!

                    Comment


                    • #11
                      Ich hab's mit TQuery und Paradox-DB ausprobiert. Sobald der Feldtyp spezifiziert ist, wird anscheinend eine Konvertierung zum Feldtyp vorgenommen. Es ist mir nur gelungen NULL-Werte zu erreichen, indem ich die Felder komplett aus dem Insert-SQL herausgenommen habe

                      Comment


                      • #12
                        Mein Problem bezieht sich auf eine Paradox-Tabelle. Auch ich habe mit TParam.DataType und TParam.Value "gespielt" und bin zum selben Ergebnis wie Jochen gekommen. Also bleibt nur die Methode <B>IBM</B> (<B>I</B>mmer <B>B</B>esser <B>M</B>anuell):

                        <PRE>
                        procedure TForm1.btnInsertIntoTableClick(Sender: TObject);
                        var
                        SpaltenStr: string;
                        ValuesStr: string;
                        begin
                        with Query1 do begin
                        Close;

                        SQL.Clear;
                        SQL.Add('INSERT INTO "Customer.db"');

                        { Wir basteln uns den SQL-String für die Spaltenliste und für VALUES }
                        SpaltenStr := '(';
                        ValuesStr := 'VALUES(';
                        if (edKundenNr.Text <> '') then begin
                        SpaltenStr := SpaltenStr + 'KundenNr' + ',';
                        ValuesStr := ValuesStr + edKundenNr.Text + ',';
                        end;
                        SpaltenStr := SpaltenStr + 'Kundenname';
                        ValuesStr := ValuesStr + '"' + edKundenname.Text + '"';
                        if (edKundeSeit.Text <> '') then begin
                        SpaltenStr := SpaltenStr + ',' + 'KundeSeit';
                        ValuesStr := ValuesStr + ', "' + edKundeSeit.Text + '"';
                        end;
                        SpaltenStr := SpaltenStr + ')';
                        ValuesStr := ValuesStr + ')';

                        SQL.Add(SpaltenStr);
                        SQL.Add(ValuesStr);

                        Prepare;
                        ExecSQL;
                        Unprepare;
                        end;
                        end;
                        </PRE>

                        Diese "manuelle" Programmierung kann sehr kompliziert sein (z.B. Trennen der Spalten und VALUES-Werte durch Kommata - so diese überhaupt vorhanden sind) und hat gegenüber der parametrisierten Abfrage Geschwindigkeitsnachteile. Aber wenn's nicht anders geht?!

                        Mein Beispiel ist natürlich weltfremd, da auch völlig leere Datensätze abgespeichert werden können. Hat man irgendwelche Schlüssel gesetzt, kommt es zu einem Indexfehler.

                        Grüße an alle. Wolfgan

                        Comment

                        Working...
                        X