Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Обсуждение возникших проблем, предложений и ошибок dbExpress драйверов
Ответить
alexer
Сообщения: 5
Зарегистрирован: Пт 29 май 2015 12:22

Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение alexer » Пн 21 ноя 2016 15:33

Попытка установить параметр coFetchAll=false приводит к ошибке "таблица не найдена" (dbх для Delphi-7).

Если одновременно установить coCursorWithHold=true, то становится лучше (таблицы находятся), но половина запросов заканчивается сообщением:

SQL Server Error: Assertion failure (D:\Projects\Delphi\Dac\PostgreSql\Source\PgSQLProtocol.pas, line 1342)

Работать в режиме coFetchAll=true, не есть целесообразно.

Подскажите, что делать?

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение AndreyZ » Вт 22 ноя 2016 13:22

Мы не смогли воспроизвести описанные вами проблемы. Постарайтесь составить небольшой пример для их воспроизведения и прислать нам через форму контакта на нашем сайте: https://www.devart.com/company/contactform.html . При помощи стандартной утилиты pg_dump создайте дамп тестовой базы и включите в пример. Также сообщите полную версию PostgreSQL, на котором воспроизводятся проблемы.

alexer
Сообщения: 5
Зарегистрирован: Пт 29 май 2015 12:22

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение alexer » Пт 09 дек 2016 15:46

Работаю в PostgreSQL 9.4. Для того, чтобы не подставлять схему в каждый запрос даю в connection команду q.sql.Add('set schema ''data'' '); q.ExecSql. Все прекрасно работает, но по умолчанию для драйвера почему-то установлена опция coFetchAll=true (читать все записи курсора на клиента)

Если установbть coFetchAll=false, то любая таблица, заданная без префикса схемы, перестает находится.

В поддержку написал письмо и выслал пример на Delphi-7. Ответа нет более 2-х недель.

Придется наверное самому написать анализатор SQL и подставлять схему в нужные места запросов, т.к. работать в режиме coFetchAll=true слишком медленно.

Кстати почему такое значение опции coFetchAll по умолчанию, например для ORACLE драйвера правила умолчания coFetchAll=false???

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение AndreyZ » Ср 14 дек 2016 09:53

К сожалению, мы не получали подобных писем с примером. Пожалуйста, пришлите этот пример на почту andreyz*devart*com .

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение AndreyZ » Пт 16 дек 2016 13:23

Мы получили ваш пример на почту, однако воспроизвести описанное вами поведение не удалось:

1. Мы получали ошибку 'SQL Server Error: отношение "od_operators" не существует.' при выполнении строки кода:

Код: Выделить всё

  SimpleDataSet1.Active:=true; 
2. Вместо сообщения об ошибке 'SQL error: function bitand(integer, integer) not found', мы получили в гриде одну запись со значением 0 при выполнении следующего кода:

Код: Выделить всё

SimpleDataSet1.DataSet.CommandText := 'select data.f_Setin(1,1) '; 
SimpleDataSet1.Active:=true; 
Пожалуйста, пришлите нам дамп тестовой базы, сделанный стандартной утилитой pg_dump (она входит в стандартную поставку pgAdmin).

alexer
Сообщения: 5
Зарегистрирован: Пт 29 май 2015 12:22

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение alexer » Пт 16 дек 2016 19:34

У меня база весит 10 гигов, выслать не смогу, могу предоставить доступ.

Но я кажется понял в чем ошибка. Я задублировал процедуру в схеме PUBLIC и процедура нашлась.

В режиме coFetchAll=false драйвер видит только схему PUBLIC и не видит никаких других схем, как бы их не задавать (в опциях драйвера или в префиксе таблицы или процедуры).

Драйвер игнорирует все команды "set search_path ..." и "set schema ..." и ищет объекты в схеме Public.

Попробуйте написать в схеме XXX процедуру YYY и ZZZ, так чтобы YYY вызывала ZZZ.

ExecProc('YYY') выдаст ошибку:
SQL error: function ZZZ not found

PS

У меня в базе вообще нет схемы PUBLIC. Попробуете прогнать тесты драйвера без схемы Public.

В режиме coFetchAll=TRUE драйвер работает нормально, т.е. не надеится на схему Public, которая где -то в нем зашита!!!

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: Не работает параметр coFetchAll=false для драйвера dbxpgs38.exe

Сообщение AndreyZ » Ср 21 дек 2016 12:33

Мы получили ваш пример с дампом. Установка параметра соединения coFetchAll=false не является причиной указанных вами ошибок. Delphi 2006 и более ранние версии имеют ограничение для установки расширенных опций драйвера, в т.ч. и опции SchemaName. Поэтому в Deplhi 7 строка кода

Код: Выделить всё

SQLConnection1.Params.Values['SchemaName'] := 'data';
не установит data текущей схемой для соединения.

О том как использовать расширенные опции в dbExpress driver for PostgreSQL для Delphi 7 - Delphi 2006, вы можете прочесть в Readme.html файле. Этот файл находится в папке, куда был установлен dbExpress driver for PostgreSQL.

Для решения проблемы вам необходимо установить расширенные опции драйвера FetchAll и SchemaName в событии AfterConnect соединения. Например:

Код: Выделить всё

procedure TForm1.SQLConnection1AfterConnect(Sender: TObject);
const
  coFetchAll = TSQLConnectionOption(301); //boolean
  coSchemaName = TSQLConnectionOption(28); // string
begin
  SQLConnection1.SQLConnection.SetOption(coFetchAll, Integer(False));
  SQLConnection1.SQLConnection.SetOption(coSchemaName, Integer(PChar('data')));
end;
А для выполнения SQL запросов достаточно использовать такой код:

Код: Выделить всё

  SimpleDataSet1.Active:=false;
  SQLConnection1.Connected:=false;
  SimpleDataSet1.DataSet.CommandText := 'select data.f_AsInteger('12345') from data.duals';
  SQLConnection1.Connected:=true;
  SimpleDataSet1.Active:=true;

Ответить