Пользователи, сталкивающиеся с разработкой приложений на языке Delphi и использующие компоненты ADO для взаимодействия с базой данных SQL Server, могут столкнуться с проблемой, когда первый параметр в запросе не передается в базу данных. В данной статье мы рассмотрим эту проблему и предложим решение, основанное на использовании компонентов ADO в среде разработки Delphi.
Описание проблемы
Пользователь столкнулся с тем, что при использовании объекта ADO Command для генерации параметризованных запросов к SQL Server, все параметры, кроме первого, передаются корректно. Пример запроса:
SELECT ?, ?, ?, ?, ?
Используя ADO Command для добавления параметров:
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 1));
command.Parameters.Append(command.CreateParameter('', adInteger, adParamInput, 0, 2));
// и так далее для остальных параметров
При профилировании запроса видно, что первый параметр имеет значение NULL:
Пользователь подтвердил, что перед вызовом метода Execute параметр имеет значение.
Подтвержденное решение
Проблема заключается в том, что в метод Execute объекта Command вместо параметра Parameters передается значение Null. Правильным решением будет использование параметра EmptyParam:
Это изменение необходимо, так как Parameters должен быть инициализирован как объект, совместимый с необязательным параметром OLE. Также можно использовать OleVariant(cmd).Execute.
Дополнительную информацию можно найти в документации по методу Execute объекта ADO Command.
Пример кода
Вот пример программы на Delphi, который демонстрирует корректное использование параметров в объекте Command:
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, EmptyParam, 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.
Заключение
При работе с ADO Command в Delphi важно помнить о правильном использовании параметров, особенно когда речь идет о передаче значений в базу данных. Использование EmptyParam вместо Null в методе Execute позволит избежать описанной проблемы и обеспечит корректную работу параметризованных запросов.
Пользователь столкнулся с проблемой передачи параметров в ADO Command для SQL Server в среде Delphi, где первый параметр не корректно обрабатывается и передается как NULL.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS