Come posso usare i parametri ADO in fase di esecuzione a Delphi 2006?
-
27-10-2019 - |
Domanda
Ho sbattuto la testa contro la scrivania con questo. Ho una tabella semplice con 2 colonne, come così:
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]
Sto cercando di aggiornare una riga con una procedura come questa:
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
Quello che vedo accadere (con quelle chiamate di debug MessageBox) è che il comando di aggiornamento ottiene 2 parametri, ma i loro nomi sono param1 e param2, non il valore e il takey.
C'è un modo per impostare i parametri in fase di esecuzione in modo che le chiamate parambyname funzionino con i nomi che desidero effettivamente, piuttosto che il param* n* che sto ottenendo?
Soluzione
Non chiamare Refresh
sui "parametri" dopo aver assegnato il "tasto di comando". Quando si chiama "Aggiorna", il VCL si rivolge al provider per le informazioni sui parametri e se le informazioni restituite non contengono nomi dei parametri, il VCL li costituisce al volo.
Altri suggerimenti
È possibile utilizzare parsesql per generare i parametri
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;