【问题标题】:How to get a value using SQL in Delphi and setting the value to a variable?如何在 Delphi 中使用 SQL 获取值并将值设置为变量?
【发布时间】:2016-07-01 12:52:56
【问题描述】:

我试图从表格中获取药物的价格,但我只是得到:

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;

【问题讨论】:

  • dmHospital.qryPrices.SQL 是您的 sql 文本。请改用dmHospital.qryPrices.Open
  • 另外dmHospital.qryPrices.SQL.Add('SELECT Price(R) FROM MedicationPrices WHERE Medication = quaotedstr(sMedication)'); 也不正确。请改用'SELECT Price(R) FROM MedicationPrices WHERE Medication= ' + QuotedStr(sMedication)
  • 请不要在你的q中发布假代码。

标签: sql delphi ms-access delphi-2010


【解决方案1】:

您应该修改您的代码以实际工作: 我的建议是使用参数而不是 QuotedStr:

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;

(请注意,在 ADOQuery 中您将使用 .Parameters 而不是 .Params)

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

问候

【讨论】:

    【解决方案2】:

    您没有正确使用查询。 qryPrices.SQL 是 SQL 语句本身。这只是文字。您需要做一些事情来实际运行该语句。 (见下文。)

    您还在引号内嵌入了变量,这意味着它没有被评估,也没有对(拼写错误的)QuotedStr 的函数调用。没有功能quaotedStr()。如果您坚持连接 SQL 的糟糕想法,则需要正确执行。如果您要清除然后添加,您可以分配给SQL.Text,而不是一步完成:

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

    此外,在您实际执行之前,查询不会执行任何操作。您需要使用qryPrices.Open 运行SELECT 语句,或使用qryPrices.ExecSQL 运行INSERTUPDATEDELETE 语句。

    您应该立即摆脱连接 SQL 的想法(在养成习惯之前)并学习使用参数化查询。它允许数据库驱动程序为您处理格式化、转换和引用,它还可以防止 SQL 注入,从而使其他人可以访问您的数据。这是一个可以帮助您入门的更正版本。

    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;
    

    【讨论】:

    • 不检查数据集中有没有返回记录吗?
    • @Guido:不。如果没有返回记录,那么读取该字段将返回一个空字符串。不知道你为什么不赞成我的回答,因为它是正确的,做事正确,并且包含对错误和解决方法的完整解释。
    • @GuidoG 在大多数情况下,这不是必需的。如有必要,可以检查结果。
    【解决方案3】:

    没有测试过(这里没有 Delphi),但应该是这样的:

    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);  
    

    【讨论】:

    • Boo 用于字符串连接和在 SQL 数据集上使用 RecordCount。 (改用参数和IsEmpty。)不要教新用户不好的技术;相反,从一开始就正确地教他们。
    • @GuidoG RecordCount 通常通过从服务器获取所有记录来实现。如果您打算迭代所有记录,那没关系,但如果您只是检查结果集是否为空(使用 IsEmpty)或者如果您在网格中显示数据,则最好避免它会获取它如所须。这在小型结果集上不是问题,但在有数百万条匹配记录时可能会出现。所以最好养成在这种情况下使用 IsEmpty 的习惯。
    • 谢谢你给了我一些新东西。
    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 2021-02-07
    • 2020-05-11
    • 2011-02-13
    相关资源
    最近更新 更多