Я использую объект ADO Command для генерации параметризованных запросов к SQL Серверу.
Если я генерирую и предоставляю несколько параметров, все параметры передаются значения - кроме первого .
Если вы представляете запрос вроде:
SELECT ?, ?, ?, ?, ?
И используйте объект команды ADO для предоставления значений параметров:
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 1);
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 2);
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 3);
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 4);
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 5);
Вы можете использовать Profiler, чтобы увидеть, что значение первого параметра равно нулю:
exec sp_executesql N'SELECT @P1, @P2, @P3, @P4, @P5',N'@P1 int,@P2 int,@P3 int,@P4 int,@P5 int',NULL,2,3,4,5
Я пробовал с ним разные типы, в разных запросах, в разных порядках. Это всегда первый параметр, который отказывается передавать на сервер базы данных.
И я могу подтвердить, что параметр имеет значение перед вызовом Execute:
command.Parameters[0].Value
Что я делаю не так?
- Клиент: Windows Vista, Windows 7, Windows 10
- Поставщик OLEDB: SQLOLEDB, SQLNCLI11, MSOLEDB SQL
- Сервер: SQL Сервер 2000, SQL Сервер 2005, SQL Сервер 2008 R2, SQL Сервер 2012, SQL Север 2017
- Компилятор : Delphi 5, Delphi XE6, Delphi 10,3 Electri c Boogaloo
CMRE
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
ActiveX,
ComObj,
ADOint,
Variants;
procedure Main;
var
cs: string;
cn: Connection;
cmd: Command;
p: _Parameter;
recordsAffected: OleVariant;
begin
cs := 'Provider=SQLOLEDB;Data Source=screwdriver;User ID=frog;Password=hunter2';
cn := CoConnection.Create;
WriteLn('Connecting to database...');
cn.Open(cs, '', '', Integer(adConnectUnspecified));
cmd := CoCommand.Create;
cmd.CommandType := adCmdText;
cmd.CommandText := 'IF ? IS NULL RAISERROR(''It was null'', 16, 1);';
cmd.Parameters.Append(cmd.CreateParameter('', adinteger, adParamInput, 0, 1));
cmd.Set_ActiveConnection(cn);
WriteLn('Executing command');
cmd.Execute({out}recordsAffected, Null, adExecuteNoRecords);
end;
begin
try
CoInitialize(nil);
Main;
WriteLn('Success');
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
end;
end;
WriteLn('Press enter to close...');
ReadLn;
end.
Чтение бонуса