Увидев, что этот вопрос какое-то время оставался без ответа, я подумал, что попытаюсь заставить код работать, не используя подсказки из комментариев, и обнаружил, что это не так просто, как я себе представлял.
Я сразу застрял с параметрами SP. я нашел это
http://docwiki.embarcadero.com/RADStudio/XE5/en/TFDQuery,_TFDStoredProc_and_TFDUpdateSQL_Questions
что говорит
"If you have difficulties with manual definition of parameters,
populate the Params collection automatically and check how the
parameters are defined. Then compare that to your code. "
но я не смог найти способ «автоматически» заполнить параметры. Я спросил в группе новостей EMBA FireDac, и автор FD, Дмитрий Арефьев, любезно объяснил, что вы можете сделать это, проверив, что FetchOptions включает fiMeta, а затем очистив и установив StoredProcName FDStoredProc.
Использование StoredProc в демонстрационной базе данных pubs на моем SqlServer определяется следующим образом:
create procedure test(@ANumber int, @AName varchar(20))
as
begin
select
@ANumber * 2 as "Number",
@AName + @AName as "Name"
end
Я изменил пару разделов кода OP следующим образом.
[...]
LSP.Params.Clear;
LSP.StoredProcName := '';
LSP.FetchOptions.Items := LSP.FetchOptions.Items + [fiMeta];
LSP.StoredProcName := aSPName;
LSP.Prepare;
Assert(LSP.ParamCount > 0);
for i := 0 to aParams.Count - 1 do
begin
LSP.Params.ParamByName(aParams[i].Name).Value := aParams[i].Value;
end;
[...]
procedure TForm21.Button1Click(Sender: TObject);
var
LParams: TFDParams;
Param : TFDParam;
begin
LParams := TFDParams.Create;
Param := LParams.Add;
Param.Name := '@ANumber';
Param.Value := 612;
Param := LParams.Add;
Param.Name := '@AName';
Param.Value := '2008';
ExecuteStoredProc('test', LParams);
end;
и это работало нормально.
ОП упоминает в вопросе, что у него сначала возникла проблема с тем, что SP не удалось выполнить, но он обнаружил, что это сработало, если он «[отбросил] компонент и настроил параметры в коде», поэтому я подумал, что я бы включите сюда консольное приложение, где конечно обязательно все делается в коде. Это было несложно, но время, которое мне потребовалось, чтобы правильно понять пункт «Использование», является моей основной причиной публикации этого ответа в качестве ответа для дальнейшего использования. Без правильного использования вы получаете ошибки, жалующиеся на отсутствие различных фабрик классов.
Консольное приложение (создано и протестировано в XE6):
program ConsoleStoredProcProject3;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, FireDac.DApt, FireDAC.Stan.Def, FireDAC.Stan.ASync,
FireDAC.Stan.Param, FireDAC.Stan.Option, FireDAC.Comp.Client,
FireDAC.Phys.MSSQL, VCL.ClipBrd;
procedure TestSP;
var
Connection : TFDConnection;
StoredProc : TFDStoredProc;
Param : TFDParam;
begin
Connection := TFDConnection.Create(Nil);
Connection.DriverName := 'MSSQL';
Connection.Params.Values['Server'] := // your server name'';
Connection.Params.Values['Database'] := 'pubs';
Connection.Params.Values['user_name'] := 'user'; // adjust to suit
Connection.Params.Values['password'] := 'password'; // ditto
Connection.LoginPrompt := False;
Connection.Connected := True;
StoredProc := TFDStoredProc.Create(Nil);
StoredProc.Connection := Connection;
StoredProc.FetchOptions.Items := StoredProc.FetchOptions.Items + [fiMeta];
StoredProc.StoredProcName := 'test';
StoredProc.Prepare;
Param := StoredProc.Params.ParamByName('@ANumber');
Param.Value := 333;
Param := StoredProc.Params.ParamByName('@AName');
Param.Value := 'A';
StoredProc.Active := True;
WriteLn(StoredProc.FieldByName('Number').AsInteger);
WriteLn(StoredProc.FieldByName('Name').AsString);
ReadLn;
end;
begin
try
TestSP;
except
on E: Exception do
Clipboard.AsText := E.Message;
end;
end.
person
MartynA
schedule
30.07.2014