[fpc-pascal] How can retrive value from OUT parameter?

Marcos Douglas md at delfire.net
Fri Apr 19 14:22:31 CEST 2013


On Fri, Apr 19, 2013 at 4:26 AM, Toru Takubo <takubo at e-parcel.co.jp> wrote:
> Hi Dmitry,
>
> Thank you very much for your advice. I am sure your
> code should work, but unfortunately I can not modify
> the existing stored procedures.
>
> I will explain what I have been trying so far.
> Suppose you are using the following stored procedure,
>
> ----------------------------------------------
> CREATE procedure [dbo].[IncValue]
>
>   @Param int OUTPUT
>
> AS
>
> SET NOCOUNT ON
>
> set @Param = @Param + 1
>
> return 100
> ----------------------------------------------
>
>
> The original program uses TADOStoredProc in Delphi 7,
> which is very easy to handle stored procedure.
> How to use it is like this:
>
> var
>   r,i: Integer;
>   DBP: TADOStoredProc;
> begin
> ...
>    DBP.ProcedureName:='IncValue';
>    DBP.Parameters.Refresh;
>    DBP.Parameters.ParamValues['@Param']:=3; //set @Param as 3
>    DBP.ExecProc;
>    r:=DBP.Parameters.ParamValues['@RETURN_VALUE']; //got r=100, OK!
>    i:=DBP.Parameters.ParamValues['@Param']; //got i=4, incremented OK!
>
>
>
> If you don't have TADOStored, still you can do the equivalent thing
> by using TADOQuery. (a little tricky, though...)
>
> var
>   r,i: Integer;
>   DBQ: TADOQuery;
> begin
> ...
>    DBQ.SQL.Text:='IncValue';
>
> DBQ.Parameters.CreateParameter('@RETURN_VALUE',ftInteger,pdReturnValue,0,0);
>    DBQ.Parameters.CreateParameter('@Param',ftInteger,pdInputOutput,0,3);
> //set @Param as 3
>    DBQ.Parameters.Command.CommandType:=cmdStoredProc;
>    DBQ.ExecSQL;
>    r:=DBQ.Parameters.ParamValues['@RETURN_VALUE']; //got r=100, OK!
>    i:=DBQ.Parameters.ParamValues['@Param']; //got i=4, incremented OK!
>
>
>
> With analogical thinking, I expected that the following might work
> for TSQLQuery in FPC:
>
> var
>   r,i: Integer;
>   DBQ: TSQLQuery;
> begin
> ...
>    DBQ.SQL.Text:='IncValue :@Param';
>    DBQ.Params.CreateParam(ftInteger,'@RETURN_VALUE',ptResult);
>    DBQ.Params.CreateParam(ftInteger,'@Param',ptInputOutput).AsInteger:=3;
>    DBQ.ExecSQL;
>    r:=DBQ.ParamByName('@RETURN_VALUE').AsInteger; //got r=0, NG
>    i:=DBQ.ParamByName('@Param').AsInteger; //got i=3, unchanged NG
>
> It does not work as I expected.
>
>
> I read fpc db tutorials and googled, but I could not find the answer for
> this specific issue. Would anyone have an idea which of the following
> is the truth?
>
> 1. My program is wrong or incomplete.
> 2. TSQLQuery (or TMSSQLConnection) does not support OUTPUT parameter.
> 3. TSQLQuery should be able to handle OUTPUT parameter, but currently a bug
> exists.

Hi Toru,

You can use SQLdb, MSSQL, StoredProcs and OUTPUT params, without
problems... but you have to change a little bit your code.
1- Use a TSQLScript
2- Following your example above, use this SQL:
    declare @param int = :param
    exec IncValue @param output
    select @param as value
3- Call Open instead of ExecSQL

You can try Greyhound[1] to abstract this. See the example:

procedure TForm1.ToolButton9Click(Sender: TObject);
var
  SC: TghSQLClient;
  DS: TDataSet;
begin
  DS := nil;
  SC := TghSQLClient.Create(DM.coRemote);
  try
    SC.Script.Text := 'declare @param int = :param '#13
                    + 'exec IncValue @param output '#13
                    + 'select @param as value';
    SC.Params['param'].AsInteger := 3;
    SC.IsBatch := True;
    SC.Open(DS);
    FOwnerForm.MsgInfo(DS.FieldByName('value').AsString);
  finally
    DS.Free;
    SC.Free;
  end;
end;

[1] https://github.com/mdbs99/Greyhound
(please, see the dev-0.1.6 branch for new features and changes)

Marcos Douglas



More information about the fpc-pascal mailing list