【问题标题】:How to pass string parameters to an TADOQuery?如何将字符串参数传递给 TADOQuery?
【发布时间】:2013-04-13 15:11:49
【问题描述】:

使用 Delphi 2010

谁能告诉我我的代码做错了什么。 cmets 显示了我在尝试将参数传递给 ADOQuery 的特定方法时收到的错误

procedure CreateAdminLogin(const APasswd: string);
var
  qry: TADOQuery;
  //P1, P2: TParameter;
begin
  qry := TADOQuery.Create(nil);
  try
    qry.Connection := frmDataModule.conMain;
    qry.SQL.Text := 'INSERT INTO Users (User_Id, Password) VALUES (:u, :p)';

    //Syntax error in INTO statement
    qry.Parameters.ParamByName('u').Value:= 'Admin';
    qry.Parameters.ParamByName('p').Value:= GetMd5(APasswd);


    //invalid variant operation
    {qry.Parameters.ParamByName('u').Value.AsString:= 'Admin';
    qry.Parameters.ParamByName('p').Value.AsString:= GetMd5(APasswd);}

    //invalid variant operation
    {P1:= qry.Parameters.ParamByName('u');
    P1.Value.asString:= 'Admin';
    P2:= qry.Parameters.ParamByName('p');
    P2.Value.asString:= GetMd5(APasswd);}


    qry.Prepared := True;
    qry.ExecSQL;
  finally
    qry.Free;
  end;

end;

注意:GetMD5 声明如下

function GetMd5(const Value: String): string;
var
  hash: MessageDigest_5.IMD5;
  fingerprint: string;
begin
  hash := MessageDigest_5.GetMd5();
  hash.Update(Value);
  fingerprint := hash.AsString();
  Result := fingerprint;
end;

谢谢

【问题讨论】:

  • 不带参数的插入是否有效?
  • 不,我收到错误“INTO 语句中的语法错误”我试过 1.) qry.SQL.Text := 'INSERT INTO Users (User_Id, Password) VALUES (Admin, Admin))';我尝试了 2.) 在每个周围使用quotedStr(例如 QuotedStr('Admin') )
  • 好吧,你必须先解决这个问题。由于您的语法看起来不错,因此它肯定取决于您要连接的数据库引擎。一旦能够成功执行不带参数的语句,就可以开始添加参数了。
  • 所有其他 SQL 在我的应用程序中都可以正常工作,所以我认为没有数据库问题。我说我不认为,因为这是我尝试做的第一个插入。其他一切都是选择查询。用户表中有一个 ID 字段。但它是自动增量的。我必须在我的插入中做任何事情吗?
  • 是的,尝试将两个值都作为 'Admin' 传递,带和不带参数,但仍然得到相同的错误

标签: delphi delphi-2010


【解决方案1】:

这对我来说很好用,使用 Delphi 附带的 DBDemos.MDB 文件(默认安装为 C:\Users\Public\Documents\RAD Studio\9.0\Samples\Data\dbdemos.mdb

ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('INSERT INTO Country (Name, Capital, Continent, Area, Population)');
ADOQuery1.SQL.Add('VALUES (:Name, :Capital, :Continent, :Area, :Population)');

ADOQuery1.Parameters.ParamByName('Name').Value := 'SomePlace';
ADOQuery1.Parameters.ParamByName('Capital').Value := 'Pitsville';
ADOQuery1.Parameters.ParamByName('Continent').Value := 'Floating';
ADOQuery1.Parameters.ParamByName('Area').Value := 1234;
ADOQuery1.Parameters.ParamByName('Population').Value := 56;
ADOQuery1.ExecSQL;
ADOQuery1.Close;

// Open it to read the data back
ADOQuery1.SQL.Text := 'SELECT * FROM Country WHERE Name = :Name';
ADOQuery1.Parameters.ParamByName('Name').Value := 'SomePlace';
ADOQuery1.Open;
ShowMessage(ADOQuery1.FieldByName('Name').AsString);

【讨论】:

  • 作为对那些可能被误导的人的澄清,TADOQueryExecSQL 方法不会使组件处于Active = True 状态,因此第一个Close 调用在此答案(ExecSQL 之后的那个)是不必要的,尽管无害。
【解决方案2】:

对于使用like 的额外注意事项:

这样的数据源 SQL

select * from Table where Phone like :param

DataModule.findQuery.Parameters.ParamByName('param').Value:= '%%'+yourEdit.Text + '%%';

【讨论】:

    【解决方案3】:

    你应该先创建参数:

    procedure CreateAdminLogin(const APasswd: string);
    var
      qry: TADOQuery;
    begin
      qry := TADOQuery.Create(nil);
      try
    
       // this part is missed in your code
       with qry.Parameters.AddParameter do
        begin
          Name := 'u';
          DataType := ftString;
        end;
        with qry.Parameters.AddParameter do
        begin
          Name := 'p';
          DataType := ftString;
        end;
    
        qry.Connection := frmDataModule.conMain;
        qry.SQL.Text := 'INSERT INTO Users (User_Id, Password) VALUES (:u, :p)';
    
        // Now it will be ok!
        qry.Parameters.ParamByName('u').Value:= 'Admin';
        qry.Parameters.ParamByName('p').Value:= GetMd5(APasswd);
    
        qry.Prepared := True;
        qry.ExecSQL;
      finally
        qry.Free;
      end;
    end;
    

    【讨论】:

    • 你不必那样做;看我的回答。 (您也不必先准备,除非您计划多次使用该查询。)
    • 2Ken White:你的例子不适合我。我猜您从某个项目中复制了示例,其中参数是从 GUI 创建的。我只是在原始代码中添加了必需的部分以使其工作。
    • 我的示例工作正常,无论有无 GUI,以及我在答案中发布的 exact 代码。除了将 ADOQuery1 放到窗体上并设置 ConnectionString 之外,IDE 中没有定义任何内容。没有添加 SQL,没有参数,没有特殊设置,注意我发布的代码中的内容。如果它对你不起作用,那么你做错了什么。 :-) 我在 D2007 和 Delphi XE 中测试过,然后在这里发布。
    • @user2106715 - 不,您的示例不起作用。我得到同样的错误。
    • 如果您只提供查询文本,将根据您的查询自动为您创建参数。因此,您所要做的就是在查询中正确使用参数(例如'select * from A where field1 = :p1'),然后您可以按名称(使用时:)或索引(使用时)引用参数?)。因此,请确保您没有执行 Params.Clear(或 Parameters.Clear),并确保 ParamCheck 为 true。
    猜你喜欢
    • 2011-06-29
    • 1970-01-01
    • 2018-05-07
    • 2016-08-02
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多