Форум » GUI » MiniGui and PostgreSQL » Ответить

MiniGui and PostgreSQL

Andrey: Что то в новой версии МиниГуи стала вылетать программа на МиниГуи. Или что то изменили в библиотеке PostgreSQL для МиниГуи ? Вот такая ошибка: [pre2]Application: D:\PgSql\Dbf_to_PostgreSQL.exe Time from start: 0 days 0 hours 3 mins 55 secs Error BASE/2020 Неверный аргумент: PQRESULTSTATUS Args: [1] = P 0x0 --------------------------------- Stack Trace --------------------------------- Called from PQRESULTSTATUS(0) Called from TPQQUERY:REFRESH(585) in module: tpostgre.prg Called from TPQQUERY:NEW(546) in module: tpostgre.prg Called from TPQSERVER:QUERY(199) in module: tpostgre.prg Called from OPEN_PGTABLE(179) in module: use_Postgres.prg Called from MYPGSQL(81) in module: Form_PostgreSQL.prg Called from (b)MAIN(119) in module: main.prg [/pre2] Куда копать то ? PS. На одном сервере прога нормально передаёт базу из 90 тыс.записей, а на другом сервере - валиться с такой ошибкой ! Уменьшил до 30 тыс.записей, всё равно валиться....

Ответов - 19

Andrey: Собрал в новой версии МиниГуи проект Convert DBF to PostgreSQL из http://hmgextended.com/applications.html Там перестал работать прелодер, т.е показ GIF файлов из модуля WaitThread.prg Почему ? Как заставить работать на новой версии МиниГуи ?

Andrey: Всем привет ! Как можно исправить ошибку в исходниках ? А то теперь периодически падает программа, несколько раз в день. Вот такая ошибка:

Andrey: Вот модуль use_Postgres.prg где происходит ошибка: [pre2]// Проверка на существование таблицы FUNCTION MyIsTablePg( cNamePgTable, oSrvPg ) LOCAL oTbl, cTable, lSeek := .f. cTable := LOWER( cNamePgTable ) oTbl := oSrvPg:ListTables() // строка 122 ? cNamePgTable ? "Список таблиц сервера PostgreSql :" ?? oTbl ; ? "-" ?v oTbl ; ? "-" [/pre2] И что здесь править и как ?


vvv: PGRESULTSTATUS(0) : насколько я понял по тексту tpostgre.prg - вместо 0 должен стоять результат обычного запроса по выбору имен таблиц. Если 0 - значит запрос по какой-то причине перестает правильно срабатывать. Может сбиваются входные параметры типа схемы или имени базы, может связь с сервером прерывается, а может служебные таблицы блокируются кем-то или чем-то для чтения.

Andrey: Везде по тексту tpostgre.prg вижу примерно такое: [pre2] result := ( PQresultStatus( res ) == PGRES_COMMAND_OK ) [/pre2]в postgres.ch стоит вот так: [pre2]/* PQresultStatus() */ #define PGRES_EMPTY_QUERY 0 #define PGRES_COMMAND_OK 1 #define PGRES_TUPLES_OK 2 #define PGRES_COPY_OUT 3 #define PGRES_COPY_IN 4 #define PGRES_BAD_RESPONSE 5 #define PGRES_NONFATAL_ERROR 6 #define PGRES_FATAL_ERROR 7[/pre2] Т.е. возврат должен быть числовой - N А в ошибке идёт: [pre2]Error BASE/2020 Неверный аргумент: PQRESULTSTATUS Args: [1] = P 0x0 --------------------------------- Stack Trace --------------------------------- Called from PQRESULTSTATUS(0) [/pre2] Почему ? И что такое P ?

SergKis: Andrey пишет И что такое P ? Point указатель на память с ответом\результатом вып. команды METHOD ListTables() CLASS TPQserver ... res := PQexec( ::pDB, cQuery ) // выясняй, что тут в res IF PQresultStatus( res ) == PGRES_TUPLES_OK ... Версии клиента и сервера (dll-ки) совпадают ?

vvv: Ошибка возникает при использовании метода TPQSERVER:LISTTABLES(). В процессе реализации метода (далее по тексту tpostgre.prg) выполняется запрос к служебной таблице "information_schema.tables". Текст запроса примерно такой: "SELECT table_name FROM information_schema.tables WHERE table_schema = 'bla-bla-bla' AND table_type = 'BASE TABLE'" Результатом выполнения запроса является "res" - что-то типа таблицы, из которой потом заносятся имена таблиц в массив "result". Далее идет проверка полученного результата IF ( ::lError := PQresultStatus( res ) != PGRES_TUPLES_OK ). Но вместо "res" передается 0, о чем говорит первая строка сообщения об ошибке, т.е. запрос к служебной таблице не отрабатывает должным образом. В запросе ломаться нечему, кроме названия схемы ('bla-bla-bla'). Ну или все-таки нарушается связь с сервером. А каков алгоритм запроса списка таблиц? Он периодически выполняется нормально, а потом в какой-то момент происходит сбой? Или программа работает, пока нет обращения к списку таблиц и вылетает при первой же попытке?

SergKis: vvv пишет Но вместо "res" передается 0, о чем говорит первая строка сообщения об ошибке, т.е. запрос к служебной таблице не отрабатывает должным образом. Если бы был 0, то работала цепочка, выделенная цветом [pre2] HB_FUNC( PQRESULTSTATUS ) { PGresult * res = hb_PGresult_par( 1 ); if( res ) hb_retni( PQresultStatus( res ) ); else hb_errRT_BASE( EG_ARG, 2020, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } [/pre2]

SergKis: PS Возможно, надо увеличить время timeout коннекта ? Или использовать begin sequnce и повторять запрос ?

Andrey: vvv пишет: А каков алгоритм запроса списка таблиц? Он периодически выполняется нормально, а потом в какой-то момент происходит сбой? Или программа работает, пока нет обращения к списку таблиц и вылетает при первой же попытке? У многих программа работает без ошибки. 5-6 клиентов. Только у одного периодически, т.е. несколько раз в день падает программа с такой ошибкой. Отправка записей происходит каждые 5 минут. Т.е. есть исправленные записи, то отправляются эти 2-3 записи из базы. Большая часть идёт без ошибки, только вот несколько раз за день (по разному) падает прога. Всё таки наверное пропадает коннект к базе. Вот и хотелось бы поправить исходники, чтобы ошибку локализовать и получить ошибку N, т.е. число а не P. Как это сделать ? SergKis пишет: Возможно, надо увеличить время timeout коннекта ? Это уже потом можно будет пробовать. Самое главное, вдруг у других тоже будет такое... И как тогда у них ошибку ловить ?

vvv: Отправка записей происходит каждые 5 минут. По логике при отправке или получении записей нет необходимости перечитывать список таблиц. А вот при кратковременном дисконнекте - вполне. Ради интереса, попробуй вручную разорвать коннект на работающем компе. Выдаст или нет такую ошибку?

SergKis: Andrey пишет Вот и хотелось бы поправить исходники, чтобы ошибку локализовать и получить ошибку N, т.е. число а не P. Там всегда должен быть P, т.к. это адрес памяти с ответом, ответа нет 0 (надо пинговать соединение или увеличить timeout, просто долгий ответ). Свои запросы, как минимум, оберни в begin sequnce и повтори при 0 несколько раз, после паузы, к примеру wApi_Sleep(200) и лог на эту ситуевину. Для проверки соединения, к примеру, спрашивай версию сервера перед запросом, но может есть ф-я для этого с кодами ошибок соединения, я не работал с этим сервером

kkg: Я сталкивался с подобной проблемой с MS SQL. (работаю через хранимые процедуры ХП). Решилась довольно просто. Перед вызовом ХП запрашиваю входные-выходные параметры ХП и если запрос возвращает не ожидаемый тип данных, разрушаю коннект и с задержкой 3 раза пытаюсь создать новый, если успешно продолжаю, если нет ошибка. Это конечно не устранит ошибку в сети, это чаще всего не контакт в кабелях искать лучше всего через пинг с ключём /t (если есть разрывы будет видно)

Новичок: Была типичная ошибка, проблема была - не в проге, а в железке) Выяснил, оказалось проблема была в материнке, в определенные моменты вылетала сетка (оказалось изначальная болезнь материнки - сетевая карта - решил установкой старого драйвера которое поставлялось с материнкой), еще также возникали проблемы из-за сетки :) (контакты, кабель, ...) и т.д. Проверь, возможно дело не в проге... *Также, для заметки по MS Ofiice - если MS Office(Word, Excel) проблемы с лицензией, та же проблема :) вылетает ошибка - решается либо ввести лицензию, либо переустановить офис если пиратка :)

Andrey: Как в Харборе при логине к базе PostgreSQL задать имя проги ? Пробовал так: [pre2]// сделано специально, т.к. в TPQServer():NEW() нельзя задать timeout conn := PQconnectdb( "dbname = " + cDatabase + " host = " + cHost + " user = " + cUser + ; " password = " + cPass + " port = " + cPort + " connect_timeout = " + cTimeout + ; " application_name = myProga" ) IF PQstatus( conn ) != CONNECTION_OK ... ENDIF M->oServer := TPQServer():NEW( cHost, cDatabase, cUser, cPass,, schema ) ? "New TPQServer() PQstatus( oServer:pDb() ) = ", PQstatus( M->oServer:pDb() ) [/pre2] Коннект проходит, но в утилите pgAdmin 4 v 1 всё равно нет имени проги. Кто знает как можно это сделать ?

Dima: Andrey пишет: Кто знает как можно это сделать ? Может так PQexec( "SET application_name='myProga'" ) Andrey пишет: " application_name = myProga" ) Не факт но возможно тут тож кавычки нужны " application_name = 'myProga'" )

Петр: Andrey пишет: // сделано специально, т.к. в TPQServer():NEW() нельзя задать timeout You are totally wrong METHOD New( cHost, cDatabase, cUser, cPass, nPort, cSchema, hCustom ) CLASS TPQserver hCustom := { "connect_timeout" => cTimeout, "application_name" => "myProga" } oServer := TPQServer():NEW( cHost, cDatabase, cUser, cPass,, schema, hCustom) и дальше проверка на отсутствие ошибок соединения Вы построчно можете описать, что делает ваш код? И объяснить связь между conn и M->oServer?

Andrey: Петр пишет: И объяснить связь между conn и M->oServer? Подозревал я что неправильно написал, т.е. 2 раза делаю коннект базе, да не знал как правильно делать. Давно это было, ещё в 2015-2016 годах. До сих пор код работал и заказчиков устраивал. Но нужно было заменить кое что и пришлось править весь код. Спасибо БОЛЬШОЕ Петр !

Andrey: Петр пишет: hCustom := { "connect_timeout" => cTimeout, "application_name" => "myProga" } Переделал свою прогу. Нет в PG admine 4 имя проги конекта к базе. Пустота.



полная версия страницы