![]() |
Datenbank: Access • Version: 2000 • Zugriff über: ADO
AdoQuery Parameterübergabe für SQL "IN" Operator
Hallo!
Folgendes Problem quält mich schon eine Weile ... Ich möchte aus einer Tabele, die mehrere Störtexte enthält, einige anzeigen. Zu jedem Störtext gehört ein Gerätetyp (Typ Zahl), die der User einzeln auswählen kann. Um nicht eine überdimensionale ODER-Verknüpfung zu basteln, will ich den IN Operator benutzen. Ich greife mit einer TADOQuery auf eine Access 2000 DB zu. In Access sieht die Where Klausel wie folgt aus und funktioniert. WHERE ((tblGer.gerTyk) In (13,15,16))) In meinem Programm so:
Delphi-Quellcode:
Wobei ich die Parameter jetzt reingeschrieben habe. Diese werden anhand von Checkboxen ermittelt. Nach Ausführern der Query bleibt die Datenmenge leer. Trage ich nur '15' oder 15 ein funktioniert es einwandfrei. Muss ich dem Parameter noch irgendwie sagen, das er ein Integer Wert ist?
Query1.SQL.Add('WHERE ((tblGer.gerTyk) In (:GTypes)))') ;
Query1.Parameters.ParamValues['GTypes'] := '15,16,13' ; Gruß Michi |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Versuch mal
Delphi-Quellcode:
Query1.SQL.Add('WHERE ((tblGer.gerTyk) In :GTypes))') ;
Query1.Parameters.ParamValues['GTypes'] := '(15,16,13)' ; |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo!
Dann kommt eine Exception, das der IN Operator eine Klammer benötigt. Diese habe ich dann bei der Parameterübergabe mit eingebaut, leider ohne Erfolg. Folgendes konnte ich noch feststellen: Bis 2 Werte, durch Komma getrennt, funktioniert das ganze, ab dem 3. nicht mehr!?! Liegt das vielleicht an dem Variant Typen des Parameters? Gruß Michi |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo Michi,
dein Problem ist eventuell, dass der Parser einen numerischen Wert erkennt. Versuche doch mal den Parameter vorher zu typisieren. Überprüfen kannst du den Erfolg bzw. Misserfolg durch eine Inspektion des Parameter-Typs vor dem Query.Open(). Grüße vom marabu |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo maramu!
An eine Typüberprüfung habe ich auch schon gedacht. Nur finde ich keine passende Methode dafür. Es müsste IMO ungefähr so aussehen:
Delphi-Quellcode:
Nur kommt mit dem Punkt hinter ['GTypes'] keine neue Auswahl ...
Query1.Parameters.ParamValues['GTypes']. ...
Gruß Michi |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Vielleicht weiß jemand eine anderen Rat ...
Delphi-Quellcode:
Vielleicht hat jemand eine anderen Lösungsansatz ...
// Abfrage der Checkboxen:
if CB.Checked then GTypes := GTypes + '15,' ; if BK.Checked then GTypes := GTypes + '13,' ; if LK.Checked then GTypes := GTypes + '14,' ; if AGV.Checked then GTypes := GTypes + '1,' ; if EAGV.Checked then GTypes := GTypes + '27,' ; if FB.Checked then GTypes := GTypes + '16,' ; if TT.Checked then GTypes := GTypes + '11,' ; if Chassis.Checked then GTypes := GTypes + '14,' ; if Gabelstapler.Checked then GTypes := GTypes + '17,' ; if ReachStacker.Checked then GTypes := GTypes + '20,' ; if Saeulen.Checked then GTypes := GTypes + '21,' ; if ZM.Checked then GTypes := GTypes + '22,' ; if Smart.Checked then GTypes := GTypes + '23,' ; Query1.Active := false ; Query1.SQL.Clear ; Query1.ParamCheck := true ; Query1.SQL.Add( ...) // where Klausel, Parameter Query1.SQL.Add('WHERE ((tblGer.gerTyk) In (:GTypes)))') ; // letztes Komma entfernen GTypes := LeftStr(GTypes, length(GTypes)-1) ; // Parameter übergeben Query1.Parameters.ParamValues['GTypes'] := GTypes ; Query1.Active := true ; Michi |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo Michi,
die vielen CheckBoxen würden mir zuviel Raum im GUI einnehmen - meine Wahl wäre eine CheckListBox, die Werte (ID, NAME) für die GTypes würde ich im Ereignis OnCreate() der Form aus der entsprechenden Tabelle der Datenbank einlesen, den Schlüssel als Object und den Namen als String. Später kann man dann die Schlüsselliste so bilden:
Delphi-Quellcode:
Noch ein paar Hinweise allgemeiner Natur: Vor einem nachfolgenden Schreibzugriff auf die Eigenschaft SQL brauchst du die Eigenschaft Active einer Query nicht auf False setzen - das wird implizit gemacht. ParamCheck brauchst du nur zur Entwurfszeit einmal zu setzen - diese Einstellung ändert sich bei dir ja nicht mehr. Klammern in der WHERE-Klausel sind nur nötig, wenn du mit den Vorrangregeln bei logischen Ausdrücken nicht einverstanden bist - in deinem Fall erschweren sie nur die Lesbarkeit.
function ListOfKeys(clb: TListBox): String;
var i: Integer; s: TStrings; begin s := TStringList.Create; with clb do for i := 0 to Pred(Count) do if Checked[i] then s.Add(IntToStr(Integer(Items.Objects[i]))); s.QuoteChar := #0; Result := s.DelimitedText; s.Free; end; Die Typisierung des Parameters kannst du so vornehmen:
Delphi-Quellcode:
Wenn das SELECT-Statement sich nie ändert - das ist das Ziel der Parameterverwendung - dann muss auch die Eigenschaft SQL der Query nur einmal gesetzt werden, allerdings muss dann die Query explizit geschlossen und wieder geöffnet werden um die geänderten Parameterwerte zu berücksichtigen.
with Query.Parameters.ParamByName('GTYPES') do
begin DataType := ftString; Value := '1,2,3,4,5,6,7'; // oder wie immer du deinen String übergeben willst end; Getippt und nicht getestet. marabu |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Eine SELECT...IN-Abfrage lässt sich schlicht und ergreifend nicht parametrisieren.
|
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo Robert,
die pauschale Aussage ist nicht korrekt, die Parametrisierung mit einem einzelnen Wert (Trivialfall) ist definitiv möglich, nur mit einer Werteliste scheint sich der interne Code zur Aufbereitung der SQL communication area etwas zu verschlucken. Offensichtlich ist ftString als Datentyp für den Parameter nicht der richtige Weg. Als Zwischenlösung könnte man die "Parametrisierung" über einen FormatString abwickeln. Grüße vom marabu |
Re: AdoQuery Parameterübergabe für SQL "IN" Operat
Hallo marabu!
Zitat:
Zitat:
Eine "Parametrisierung" über einen FormatString o.ä. wäre ein gangbarer Workaround. Man verliert halt je nach verwendetem RDBMS und Datenzugriffsschicht die eventuellen Vorteile einer parametrisierten Abfrage. Aber wir sprechen hier ja von Access... :mrgreen: Ein andere Alternative wäre u.U. die Verwendung einer zweiten Tabelle à la
SQL-Code:
Allerdings habe ich keinen blassen Schimmer, ob Access sowas unterstützt.
SELECT * FROM Tabelle WHERE Wert IN (SELECT Nachschlagewert FROM Tabelle2)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz