Я выполняю запросы с именованными параметрами из 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.