2011-01-31 3 views
1

나는 이것으로 책상에 머리를 대고 있었다. 그래서 같이, 2 열이있는 간단한 테이블이 있습니다Delphi 2006에서 런타임에 ADO 매개 변수를 사용하려면 어떻게해야합니까?

CREATE TABLE [dbo].[MiscInitializers](
[PKey] [int] IDENTITY(1,1) NOT NULL, 
[Value] [text] NULL, 
CONSTRAINT [PK_MiscInitializers] PRIMARY KEY CLUSTERED 
(
[PKey] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

나는이 같은 절차를 행을 업데이트하려고 :

function TdmSQL.SetInitializer(Value: string; var Key: string): boolean; 
const 
    UpdateCmd = 
    'update MiscInitializers set Value = :theValue where PKey = :theKey'; 
    InsertCmd = 'insert into MiscInitializers (Value) values (:Param1)'; 
var 
    tmp: integer; 
    rsTmp: TADODataSet; 
    foo: TParameter; 
    sTmp: string; 
begin 
    Result := false; 
    adoGenericCommand.CommandText := ''; 
    adoGenericCommand.Parameters.Clear; 
    if Key <> '' then 
    begin 
    // attempt update 
    if not TryStrToInt(Key, tmp) then 
     exit; 
    adoGenericCommand.CommandText := UpdateCmd; 
    adoGenericCommand.Prepared := true; 
    adoGenericCommand.Parameters.Refresh; 
    // some debug stuff 
    sTmp := Format('Num Params: %d', [adoGenericCommand.Parameters.Count]); 
    ShowMessageBox(sTmp); 
    for tmp := 0 to adoGenericCommand.Parameters.Count - 1 do 
    begin 
     sTmp := Format('Param %d: Name %s', 
     [tmp, adoGenericCommand.Parameters.Items[tmp].Name]); 
     ShowMessageBox(sTmp); 
    end; 
    // end debug stuff 
    foo := adoGenericCommand.Parameters.ParamByName('theValue'); 
    foo.Value.AsString := Value; 
    foo := adoGenericCommand.Parameters.ParamByName('theKey'); 
    foo.Value := Key; 
    rsTmp.Recordset := adoGenericCommand.Execute; 
    Result := rsTmp.RecordCount = 1; 
    exit; 
    // etc 

내가 (그 디버그 메시지 박스 호출에) 일어나는 참조 update 명령이 2 개의 매개 변수를 가져 오지만 해당 이름은 theValue 및 theKey가 아닌 Param1 및 Param2입니다.

ParamByName 호출은 Param * N *이 아니라 실제로 원하는 이름으로 작동하도록 런타임에 매개 변수를 설정하는 방법이 있습니까?

답변

0

'CommandText'를 지정한 후에 'Parameters'에 Refresh을 호출하지 마십시오. '새로 고침'을 호출하면 VCL이 매개 변수 정보 제공자에게 전달되며, 반환 된 정보에 매개 변수 이름이 없으면 VCL이 매개 변수 정보를 즉시 작성합니다.

+0

귀하의 제안이 잘못을 생성하는 ParseSQL를 사용할 수 있습니다. '새로 고침'호출을 삭제해도 매개 변수가 전혀 없습니다 (예 : adoGenericCommand.Parameters.Count = 0). – wades

+0

@wades - Strange, ": Param"스타일 매개 변수는 'CommandText'를 지정할 때 초기화해야합니다. 내가 말했듯이, '새로 고침'은 공급자로부터 매개 변수 정보를 검색합니다. 'ParamCheck'는 기회 당 false가 아닙니까? –

+1

나는 이의 제기를 철회해야한다. 나는 그것을 시험 할 때 실수를 저질렀다. 실제로 새로 고침 호출을 생략하면 트릭을 수행하는 것처럼 보입니다. – wades

2

당신은 매개 변수

const 
    UpdateCmd = 'update MiscInitializers set Value = :theValue where PKey = :theKey'; 
var 
    ds: TADODataSet; 
    I: Integer; 
begin 
    ds := TADODataSet.Create(nil); 
    try 
     ds.CommandText := UpdateCmd; 
     ds.Parameters.ParseSQL(ds.CommandText, True); 
     for I := 0 to ds.Parameters.Count - 1 do 
      ShowMessage(ds.Parameters.Items[I].name); 
    finally 
     ds.Free; 
    end; 
end; 
+0

아니요,이 제안은 작동하지 않습니다. ParseSQL을 호출하면 새로 고침을 사용하는 것과 동일한 결과가 나타납니다. 즉 ds.Parameters.Items [0] .Name이 Param1 등이됩니다. – wades

+0

위의 코드를 사용해 보셨습니까? –

+0

원래 질문을 게시하기 전에이 방법을 시도해 보았습니다. 매개 변수를 열거하면 theKey 및 theValue의 이름이 각각? Param1 및? Param2로 변경되었으며 FindParam 및 ParamByName에 대한 호출은 Param1 및 Param2 만 찾습니다. . Sertac Akyuz가 정확하다는 것이 밝혀졌고 Refresh에 대한 호출이 문제였습니다. – wades

관련 문제