<div dir="ltr">It appears that SQLdb doesn't support (MS) SQL variables.<br><br>thanks,<br>Dmitry<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Apr 19, 2013 at 8:29 AM, Marcos Douglas <span dir="ltr"><<a href="mailto:md@delfire.net" target="_blank">md@delfire.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Fri, Apr 19, 2013 at 9:22 AM, Marcos Douglas <<a href="mailto:md@delfire.net">md@delfire.net</a>> wrote:<br>

> On Fri, Apr 19, 2013 at 4:26 AM, Toru Takubo <<a href="mailto:takubo@e-parcel.co.jp">takubo@e-parcel.co.jp</a>> wrote:<br>
>> Hi Dmitry,<br>
>><br>
>> Thank you very much for your advice. I am sure your<br>
>> code should work, but unfortunately I can not modify<br>
>> the existing stored procedures.<br>
>><br>
>> I will explain what I have been trying so far.<br>
>> Suppose you are using the following stored procedure,<br>
>><br>
>> ----------------------------------------------<br>
>> CREATE procedure [dbo].[IncValue]<br>
>><br>
>>   @Param int OUTPUT<br>
>><br>
>> AS<br>
>><br>
>> SET NOCOUNT ON<br>
>><br>
>> set @Param = @Param + 1<br>
>><br>
>> return 100<br>
>> ----------------------------------------------<br>
>><br>
>><br>
>> The original program uses TADOStoredProc in Delphi 7,<br>
>> which is very easy to handle stored procedure.<br>
>> How to use it is like this:<br>
>><br>
>> var<br>
>>   r,i: Integer;<br>
>>   DBP: TADOStoredProc;<br>
>> begin<br>
>> ...<br>
>>    DBP.ProcedureName:='IncValue';<br>
>>    DBP.Parameters.Refresh;<br>
>>    DBP.Parameters.ParamValues['@Param']:=3; //set @Param as 3<br>
>>    DBP.ExecProc;<br>
>>    r:=DBP.Parameters.ParamValues['@RETURN_VALUE']; //got r=100, OK!<br>
>>    i:=DBP.Parameters.ParamValues['@Param']; //got i=4, incremented OK!<br>
>><br>
>><br>
>><br>
>> If you don't have TADOStored, still you can do the equivalent thing<br>
>> by using TADOQuery. (a little tricky, though...)<br>
>><br>
>> var<br>
>>   r,i: Integer;<br>
>>   DBQ: TADOQuery;<br>
>> begin<br>
>> ...<br>
>>    DBQ.SQL.Text:='IncValue';<br>
>><br>
>> DBQ.Parameters.CreateParameter('@RETURN_VALUE',ftInteger,pdReturnValue,0,0);<br>
>>    DBQ.Parameters.CreateParameter('@Param',ftInteger,pdInputOutput,0,3);<br>
>> //set @Param as 3<br>
>>    DBQ.Parameters.Command.CommandType:=cmdStoredProc;<br>
>>    DBQ.ExecSQL;<br>
>>    r:=DBQ.Parameters.ParamValues['@RETURN_VALUE']; //got r=100, OK!<br>
>>    i:=DBQ.Parameters.ParamValues['@Param']; //got i=4, incremented OK!<br>
>><br>
>><br>
>><br>
>> With analogical thinking, I expected that the following might work<br>
>> for TSQLQuery in FPC:<br>
>><br>
>> var<br>
>>   r,i: Integer;<br>
>>   DBQ: TSQLQuery;<br>
>> begin<br>
>> ...<br>
>>    DBQ.SQL.Text:='IncValue :@Param';<br>
>>    DBQ.Params.CreateParam(ftInteger,'@RETURN_VALUE',ptResult);<br>
>>    DBQ.Params.CreateParam(ftInteger,'@Param',ptInputOutput).AsInteger:=3;<br>
>>    DBQ.ExecSQL;<br>
>>    r:=DBQ.ParamByName('@RETURN_VALUE').AsInteger; //got r=0, NG<br>
>>    i:=DBQ.ParamByName('@Param').AsInteger; //got i=3, unchanged NG<br>
>><br>
>> It does not work as I expected.<br>
>><br>
>><br>
>> I read fpc db tutorials and googled, but I could not find the answer for<br>
>> this specific issue. Would anyone have an idea which of the following<br>
>> is the truth?<br>
>><br>
>> 1. My program is wrong or incomplete.<br>
>> 2. TSQLQuery (or TMSSQLConnection) does not support OUTPUT parameter.<br>
>> 3. TSQLQuery should be able to handle OUTPUT parameter, but currently a bug<br>
>> exists.<br>
><br>
> Hi Toru,<br>
><br>
> You can use SQLdb, MSSQL, StoredProcs and OUTPUT params, without<br>
> problems... but you have to change a little bit your code.<br>
> 1- Use a TSQLScript<br>
> 2- Following your example above, use this SQL:<br>
>     declare @param int = :param<br>
>     exec IncValue @param output<br>
>     select @param as value<br>
> 3- Call Open instead of ExecSQL<br>
><br>
> You can try Greyhound[1] to abstract this. See the example:<br>
><br>
> procedure TForm1.ToolButton9Click(Sender: TObject);<br>
> var<br>
>   SC: TghSQLClient;<br>
>   DS: TDataSet;<br>
> begin<br>
>   DS := nil;<br>
>   SC := TghSQLClient.Create(DM.coRemote);<br>
>   try<br>
>     SC.Script.Text := 'declare @param int = :param '#13<br>
>                     + 'exec IncValue @param output '#13<br>
>                     + 'select @param as value';<br>
>     SC.Params['param'].AsInteger := 3;<br>
>     SC.IsBatch := True;<br>
>     SC.Open(DS);<br>
>     FOwnerForm.MsgInfo(DS.FieldByName('value').AsString);<br>
>   finally<br>
>     DS.Free;<br>
>     SC.Free;<br>
>   end;<br>
> end;<br>
><br>
> [1] <a href="https://github.com/mdbs99/Greyhound" target="_blank">https://github.com/mdbs99/Greyhound</a><br>
> (please, see the dev-0.1.6 branch for new features and changes)<br>
><br>
> Marcos Douglas<br>
<br>
</div></div>Sorry, I did not explained these:<br>
DM.coRemote = DM is a DataModule and coRemote is a instance of<br>
TghSQLConnector class.<br>
FOwnerForm.MsgInfo = change this for ShowMessage function.<br>
<br>
Best regards,<br>
<div class="HOEnZb"><div class="h5">Marcos Douglas<br>
_______________________________________________<br>
fpc-pascal maillist  -  <a href="mailto:fpc-pascal@lists.freepascal.org">fpc-pascal@lists.freepascal.org</a><br>
<a href="http://lists.freepascal.org/mailman/listinfo/fpc-pascal" target="_blank">http://lists.freepascal.org/mailman/listinfo/fpc-pascal</a><br>
</div></div></blockquote></div><br></div>