Я выполняю запросы с именованными параметрами из FireDAC в PostgreSQL 11, используя собственный драйвер FireDAC Postgres. Во время оператора подготовки FireDAC преобразует именованные параметры в позиционные параметры, что правильно. Однако, если я затем попытаюсь присвоить значения этим параметрам, FireDAC выдаст исключение «Аргумент вне диапазона». Похоже, что FireDAC не распознает сгенерированные им позиционные параметры. Например, если исходный текст SQL выглядел примерно так:
SELECT * FROM account WHERE accountid = :accid;
при вызове метода Prepare FDQuery FireDAC преобразовал этот запрос в следующий:
SELECT * FROM account WHERE accountid = $1;
Но когда я пытаюсь присвоить значение параметру, я получаю сообщение об ошибке. Задание выглядит примерно так:
FDQuery1.Params[0].AsString = strID;
где strID — строковое значение, а accountid — текстовое поле. Кроме того, если я использую что-то вроде следующего, он возвращает 0.
ShowMessage( IntToStr( FDQuery1.Params.Count ) );
Я значительно упростил этот код, но проблемы остались прежними. Как мне заставить FireDAC распознавать сгенерированные им позиционные параметры?
Обновление: как я уже говорил, приведенный выше код значительно упрощен. Что на самом деле происходит, так это то, что в нашей структуре у нас есть один набор подпрограмм, которые присваивают значения макросам FireDAC, а затем мы генерируем оператор SQL, подготавливая запрос и затем считывая свойство Text FDQuery. Этот оператор SQL затем присваивается свойству SQL.Text другого FDQuery (также динамически созданного), и именно там запрос завершается ошибкой. Итак, вот очень простой пример того, что происходит внутри кода:
var
Query: TFDQuery;
begin
Query := TFDQuery.Create( nil );
Query.Connection := PGConnection;
// In reality, the SQL statement below was generated earlier,
// from a function call where the SQL was created by the FireDAC
// SQL preprocessor, as opposed to being a literal expression
Query.SQL.Text := 'SELECT * FROM tablename WHERE field2 = $1;';
Query.Params[0].AsString := '4'; // BANG! Argument out of range
Я подумал, что это может быть связано с расширением макроса FireDAC, поэтому я добавил следующие две строки после создания экземпляра FDQuery:
Query.ResourceOptions.MacroCreate := False;
Query.ResourceOptions.MacroExpand := False;
Неа. Это тоже помогло. Я предполагаю, что FireDAC просто не распознает, что $1 является допустимым позиционным параметром в PostgreSQL.
ParamByName
вместо порядкового номера? - person JacalarRick   schedule 08.07.2019FDQuery1.Prepare
перед объявлением своих параметров? FDQuery1 определяется в коде или во время разработки? - person JacalarRick   schedule 09.07.2019