更好的传递参数给 TADOStoredProc (Delphi)的方法

8
我需要将大量SQL查询转换为存储过程。我有一些代码,在一个Delphi过程中一次更新约20或30个值。我可以创建一个存储过程来执行此操作。问题是我的参数传递方法非常笨重,像这样:
    with stored_procedure do......
    Param := Parameters.AddParameter;
    Param.Name := '@SSN';
    Param.Value := edtSSN.text;

    Param := Parameters.AddParameter;
    Param.Name := '@FirstName';
    Param.Value := edtFirstName.Text;

    Param := Parameters.AddParameter;
    Param.Name := '@LastName';
    Param.Value := edtLastName.Text;

    Param := Parameters.AddParameter;
    Param.Name := '@UserRID';
    Param.Value:= GetRIDFromCombo(cbUser);

我也不确定这是否会导致内存泄漏(是否需要释放这些TParameter对象?)

有没有更好的处理大量参数的方法?(我不能使用新库。我必须使用ADO,并且我使用的SQL是MSSQL)(另外,我不使用ADO.net)

4个回答

20

有一个已被接受的答案 :-),但是我想向您指出一种更简单、更易于定义和使用参数的方法,只需一行代码:

stored_procedure.Parameters.CreateParameter('SSN',ftString,pdInput,30,edtSSN.text);

它简单而灵活,因为您可以在同一行中定义输入和输出参数。

并且来自Delphi帮助:

function CreateParameter(const Name: WideString; DataType: TDataType;
    Direction: TParameterDirection; Size: Integer; 
    Value: OleVariant): TParameter;

2
这似乎是一个比我的更好的答案。 - Bruce McGee
谢谢Bruce和Rob,这就是SO的美妙之处,我在这里学到了很多Delphi知识,并试图与他人分享我的所知所学 :-) - Mohammed Nasman
这很方便,但是对于大量的输入参数,我仍然更喜欢第一种方式,因为它更简单。 - Earlz

11

这不会导致内存泄漏。stored_procedure将清理其参数。您可以通过在.dpr中添加以下内容并使用FastMM来确认:

  ReportMemoryLeaksOnShutdown := True;

首先,我会摒弃 "with" 语句。它可能会导致更多的问题和不够易读的代码。

我会创建一个帮助方法,接受存储过程、参数名称和参数值,这将使您的代码更易于管理。

AddParam(stored_procedure, '@SSN', edtSSN.text);
AddParam(stored_procedure, '@FirstName', edtFirstName.Text);
AddParam(stored_procedure, '@LastName', edtLastName.Text);
AddParam(stored_procedure, '@UserRID', GetRIDFromCombo(cbUser));

11

ADO会为您创建参数,您只需要在参数对象上调用Refresh即可:

 SP.Connection := SqlConnection; // must be done before setting procedure name
 sp.ProcedureName := 'MyStoredProc';
 sp.Parameters.Refresh; // This will create the parameters for you as defined in SQL Server
 sp.Parameters.ParamByName('@SSN'').Value  := SSN; // params now exist

如果有任何输出参数,你需要明确设置它们:

   sp.Parameters.ParamByName('@ReturnValue').Direction := pdInputOutput;

1
这很好,但仅在过程位于连接的默认数据库中才有效。如果使用DifferentDatabase.Owner.ProcedureName,ADO中存在一个错误会破坏参数。 - DiGi
1
我还发现.Refresh有时候甚至在同一个数据库.owner中也不起作用。我没有找到它何时起作用,何时不起作用的规律,但是当它不起作用时,我会收到类似“未找到参数'@SearchText'”的错误提示,当我使用.ParamByName时。同样的调用99.9%的时间都能正常工作。手动添加参数似乎可以避开这个问题。 - Tony
非常感谢。我在处理类型为TDate和TDateTime的参数时遇到了麻烦,因为sp.parameters.refresh创建的参数的数据类型是WideString而不是TDate。 - Kiril Hadjiev

0

这是我知道的最短的:

stored_procedure.Parameters.ParamByName('@SSN').Value := edtSSN.text;

请注意,在执行此操作之前,您需要为 stored_procedure.Connection 分配连接,并调用 stored_procedure.Parameters.Refresh;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接