2016-07-01 7 views
0

Ich versuche, den Preis der Medikamente vom Tisch zu bekommen, aber bekomme ich nur:Wie bekomme ich einen Wert mit SQL in Delphi und setze den Wert auf eine Variable?

enter image description here

procedure TForm1.BuyButtonClick(Sender: TObject); 
var 
    iAmount : integer; 
    rRate : real; 
    sMedication : string; 
    sRate : string; 
begin 
    iAmount := 0; 
    sMedication := BuyCombobox.Items[BuyCombobox.ItemIndex]; 
    dmHospital.qryPrices.SQL.Clear; 
    dmHospital.qryPrices.SQL.Add('SELECT Price(R) FROM MedicationPrices WHERE Medication = quaotedstr(sMedication)'); 
    sRate := dmHospital.qryPrices.SQL; 
    ShowMessage(sRate); 
end; 
+0

'dmHospital.qryPrices.SQL' ist Ihr SQL-Text. Verwenden Sie stattdessen "dmHospital.qryPrices.Open". –

+0

Auch 'dmHospital.qryPrices.SQL.Add ('SELECT Preis (R) VON MedicationPrices WHERE Medication = quaotedstr (sMedication)');' ist falsch. Verwenden Sie stattdessen "SELECT PREIS (R) FROM MedicationPrices WHERE Medication = '+ QuotedStr (sMedication)". –

+0

Bitte posten Sie keinen gefälschten Code in Ihrem q. – MartynA

Antwort

4

Sie sind nicht die Abfrage richtig verwenden. qryPrices.SQL ist die SQL-Anweisung selbst. Es ist nur Text. Sie müssen etwas tun, um die Anweisung tatsächlich auszuführen. (Siehe unten.)

Sie haben die Variable auch in die Anführungszeichen eingebettet, was bedeutet, dass sie nicht ausgewertet wird, und auch nicht den Funktionsaufruf für die (falsch geschriebene) QuotedStr. Es gibt keine Funktion quaotedStr(). Wenn Sie auf der schlechten Idee der Verkettung von SQL bestehen, müssen Sie es richtig machen. Wenn Sie vorhaben, zu löschen und dann hinzufügen, können Sie stattdessen einfach zu SQL.Text zuweisen es in einem Schritt zu tun:

dmHospital.qryPrices.SQL.Text := 'SELECT Price(R) FROM MedicationPrices WHERE Medication = ' + Quotedstr(sMedication); 

Außerdem wird die Abfrage nichts tun, bis Sie es tatsächlich auszuführen. Sie müssen qryPrices.Open verwenden, um eine SELECT Anweisung auszuführen, oder qryPrices.ExecSQL, um eine INSERT, UPDATE oder DELETE Anweisung auszuführen.

Sie sollten sofort aus dem Gedanken kommen, SQL zu verketten (bevor Sie sich angewöhnen) und lernen, parametrisierte Abfragen zu verwenden. Es ermöglicht dem Datenbanktreiber, die Formatierung und Konvertierung für Sie zu übernehmen und zu quotieren, und es verhindert auch die SQL-Injektion, die anderen den Zugriff auf Ihre Daten ermöglichen kann. Hier ist eine korrigierte Version, die Ihnen den Einstieg erleichtern sollte.

procedure TForm1.BuyButtonClick(Sender: TObject); 
var 
    sMedication : string; 
    sRate : string; 
begin 
    iAmount := 0; 
    sMedication := BuyCombobox.Items[BuyCombobox.ItemIndex]; 
    dmHospital.qryPrices.SQL.Text := 'SELECT Price(R) FROM MedicationPrices WHERE Medication = :Medication'; 
    dmHospital.qryPrices.Parameters.ParamByName('Medication').Value := sMedication; 
    dmHospital.qryPrices.Open; 
    sRate := dmHospital.qryPrices.FieldByName('Price(R)').AsString; 
    dmHospital.qryPrices.Close; 
    ShowMessage(sRate); 
end; 
+0

sollten Sie nicht überprüfen, ob im Datensatz ein Datensatz zurückgegeben wird? – GuidoG

+0

@Guido: Nein. Wenn kein Datensatz zurückgegeben wird, gibt das Lesen des Feldes eine leere Zeichenfolge zurück. Ich bin mir nicht sicher, warum Sie meine Antwort abgelehnt haben, da sie korrekt ist, die Dinge richtig macht und eine vollständige Erklärung enthält, was falsch war und wie Sie es beheben können. –

+0

@GuidoG In den meisten Fällen ist dies nicht notwendig. Bei Bedarf kann das Ergebnis überprüft werden. –

0

es nicht getestet (nicht Delphi hier zur Hand haben), aber es sollte so etwas wie dieses :

iAmount := 0; 
sMedication := BuyCombobox.Items[BuyCombobox.ItemIndex]; 
dmHospital.qryPrices.SQL.Clear; 
dmHospital.qryPrices.SQL.Add('SELECT Price(R) as price FROM MedicationPrices WHERE Medication = ' + QuotedStr(sMedication)); 

dmHospital.qryPrices.Open; 
if (dmHospital.qryPrices.RecordCount = 1) 
    sRate := dmHospital.qryPrices.FieldByName('price').AsString; 

ShowMessage(sRate); 
+2

Boo für die String-Verkettung und die Verwendung von RecordCount für ein SQL-Dataset. (Verwenden Sie stattdessen Parameter und 'IsEmpty'.) Bringen Sie keine schlechte Technik für neue Benutzer mit. Lerne sie stattdessen von Anfang an richtig. –

+0

jetzt bin ich neugierig, was ist falsch mit recordcount? – GuidoG

+2

@GuidoG RecordCount wird oft implementiert, indem alle Datensätze vom Server abgerufen werden. Das ist in Ordnung, wenn Sie planen, alle Datensätze trotzdem zu iterieren. Am besten vermeiden Sie es, wenn Sie nur überprüfen, ob die Ergebnismenge leer ist (IsEmpty verwenden) oder ob Sie die Daten in einem Raster anzeigen, das sie abruft wie benötigt. Dies ist bei kleinen Ergebnismengen kein Problem, könnte aber bei Millionen übereinstimmender Datensätze auftreten. Daher ist es am besten, die Gewohnheit zu verwenden, IsEmpty für Fälle wie diesen zu verwenden. –

4

Sie Ihren Code tatsächlich zu arbeiten ändern sollte: Mein Rat ist Parameter statt QuotedStr zu verwenden:

dmHospital.qryPrices.SQL.Clear; 
dmHospital.qryPrices.SQL.Add('SELECT Price(R) AS Rate FROM MedicationPrices WHERE Medication = :pMedication'); 
dmHospital.qryPrices.Params.ParamByName('pMedication').AsString=sMedication; 

(Beachten Sie, dass in ADOQuery Sie .parameters statt .params verwenden würde)

dmHospital.qryPrices.Open; 
sRate=dmHospital.qryPrices.FieldByName('Rate').AsString; 
ShowMessage(sRate); 

Grüße

Verwandte Themen