I have been banging my head against the desk with this. I have a simple table with 2 columns, like so:
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]
I am trying to update a row with a procedure like this:
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
What I see happening (with those debug messagebox calls) is that the update command gets 2 parameters, but their names are Param1 and Param2, not theValue and theKey.
Is there a way to set up the parameters at runtime so the ParamByName calls will work with the names I actually want, rather than the Param*N* that I'm getting?
Don't call
Refresh
on the 'Parameters' after you assign the 'CommandText'. When you call 'Refresh', the VCL turns to the provider for parameter information, and if the returned information does not contain parameter names then the VCL makes up them on the fly.