2011-01-31 21 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を呼び出さないでください。 '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を呼び出すと、Refreshを使用した場合と同じ結果になります。すなわちds.Parameters.Items [0] .NameはParam1などになります。 – wades

+0

上記のコードを試しましたか? –

+0

元の質問を投稿する前にその方法を試してみましたが、パラメータを列挙すると、theKeyとtheValueの名前がそれぞれ?Param1と?Param2に変更され、FindParamとParamByNameの呼び出しはParam1とParam2 。 Sertac Akyuzが正しかったことが判明し、Refreshへの呼び出しが問題でした。 – wades

関連する問題