2014-02-11 9 views
3

저는 FireDAC에 비교적 새로운입니다. 동적으로 저장 프로 시저를 호출 할 수 있기를 원합니다.FireDac을 사용하여 Delphi에서 저장 프로 시저를 동적으로 만들고 호출하는 적절한 방법은 무엇입니까?

function TForm21.ExecuteStoredProc(aSPName: string; aParams: TADParams): Boolean; 
var 
    LSP: TADStoredProc; 
    i: Integer; 
begin 
    LSP := TADStoredProc.Create(nil); 
    try 
    LSP.Connection := ADConnection1; 
    LSP.StoredProcName := aSPName; 
    LSP.Prepare; 
    for i := 0 to aParams.Count - 1 do 
    begin 
     LSP.Params[i].Value := aParams[i].Value; 
    end; 
    LSP.ExecProc; 
    finally 
    LSP.Free; 
    end; 
    Result := True; 
end; 

나는 그러나, 저장 프로 시저가 실행되지

procedure TForm21.Button1Click(Sender: TObject); 
var 
    LParams: TADParams; 
begin 
    LParams := TADParams.Create; 
    LParams.Add.Value := 612; 
    LParams.Add.Value := '2008'; 

    ExecuteStoredProc('HDMTEST.dbo.spARCHIVE_HISTORY_DATA', LParams); 
end; 

로 전화 : 지금까지 나는 다음 있습니다. 즉, 코드가 제대로 실행되고 오류 메시지가 표시되지 않지만 저장 프로 시저가 실행되지 않습니다.

추가 정보 - 구성 요소를 놓고 코드에서 params를 설정하면 잘 실행됩니다.

누구나 내가 무엇을 놓치고 있는지 알 수 있습니까?

+0

어떻게 실패? 어떤 오류 메시지? – EProgrammerNotFound

+0

죄송합니다. 아무 것도하지 않습니다. 오류 메시지가 없습니다. 코드가 실행됩니다. 나는 그 질문을 갱신 할 것이다. –

+1

ParamByName을 사용하고 매개 변수의 모든 값을 수동으로 정의하십시오. 귀하의 코드는 괜찮습니다, 문제는 매개 변수 순서에 의존해야합니다. – EProgrammerNotFound

답변

1

이 q가 잠시 동안 답변되지 않은 채로 남아있는 것을 보았을 때, 나는 코멘트에서 단서를 사용하지 않고 코드를 작동 시키려고 노력했고, 상상했던 것만 큼 쉽지 않은 것으로 생각했습니다.

나는 SP 매개 변수를 즉시 고수했다. 나는

"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. " 

를 말합니다이

http://docwiki.embarcadero.com/RADStudio/XE5/en/TFDQuery,_TFDStoredProc_and_TFDUpdateSQL_Questions

을 발견하지만 "자동으로"params 객체를 파라미터를 채우는 방법을 찾을 수 없습니다. 나는 EMBA에 묻습니다 FireDac 뉴스 그룹과 FD 작성자 인 Dimitry Arefiev는 은 FetchOptions에 fiMeta가 포함되어 있는지 확인한 다음 FDStoredProc의 StoredProcName을 지우고 설정함으로써 가능하다고 설명했습니다.

create procedure test(@ANumber int, @AName varchar(20)) 
as 
begin 
    select 
    @ANumber * 2 as "Number", 
    @AName + @AName as "Name" 
end 

내가이

[...] 
    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; 

같은 영업 이익의 코드 섹션의 몇 가지를 변경하고 괜찮 았는데 다음과 같이 술집에서 StoredProc가 사용

정의 내 SQLSERVER에 데이터베이스를 데모.

OP에서 그는 SP가 을 실행하지 못했지만 그가 구성 요소를 "떨어 뜨리고 코드에서 매개 변수를 설정"하는 경우에 문제가 있음을 발견했습니다. 나는 여기에 반드시 콘솔 응용 프로그램을 포함시킬 것이라고 생각했습니다. 물론 모든 것이 코드로 이루어졌습니다. 이것은 어렵지 않았지만 Uses 절을 올바르게 가져 오는 데 걸린 시간이 미래의 참조를 위해 답변으로 게시하는 주된 이유입니다. 올바른 용도로 사용하지 않으면 다양한 클래스 팩토리가 누락되었다고 불평하는 오류가 발생합니다. (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.