Форум » Для флейма » MiniGui + PostgreSQL » Ответить

MiniGui + PostgreSQL

Andrey: Кому будет интересно. https://habrahabr.ru/post/282764/

Ответов - 126, стр: 1 2 3 4 5 6 7 All

ММК: Andrey пишет: Что за фокус такой, открывать "SELECT * FROM test ;" ? Например с помощью ADO

Andrey: Блин, что за SQL такая непростая штука... Чтобы записать в базу несколько полей целые простыни писать приходиться.... Кому интересно (примерно так): [pre2] cMaska := 'UPDATE test SET "cnza"=?, "dtza"=?, "kmaster"=?, "qadres"=?, "qdop"=?, "qoborud"=?, "qneispr"=?, "qsrokza"=?, "qoperat"=?, "qvipza"=?, "kdate"=?, "kvipza"=?, "datesrok"=?, "datepere"=?, "rem"=?' aDim := HB_ATokens( cMaska, '?', .F., .F. ) cIdz := "'"+HB_NtoS(FIELD->IDZ)+"'" cDTDoc := "'" + TRANSFORM( DTOS(FIELD->DateDoc),"@R 9999-99-99" ) cDTDoc += " " + TRANSFORM(FIELD->TimeDoc,"@R 99:99") + ":00'" ..... IF FIELD->DATESROK == CTOD("") cDateSrok := "NULL" ELSE cDateSrok := "'" + TRANSFORM( DTOS( FIELD->DATESROK ),"@R 9999-99-99" ) + "'" ENDIF IF FIELD->DATEPERE == CTOD("") cDatePere := "NULL" ELSE cDatePere := "'" + TRANSFORM( DTOS( FIELD->DATEPERE ),"@R 9999-99-99" ) + "'" ENDIF cQuery := 'INSERT INTO "test" ("xid") VALUES (' + cIdz + ') ON CONFLICT("xid") DO NOTHING;' + CRLF cQuery += aDim[1] + "'"+ALLTRIM(TRANSFORM(FIELD->NNDOC,"99999/99"))+"'" cQuery += aDim[2] + cDTDoc // Дата + Время ввода документа ................... cQuery += aDim[13] + cDateSrok // cQuery += aDim[14] + cDatePere cQuery += aDim[15] + "'" + ALLTRIM(FIELD->MREM) + "'" // Примечание cQuery += ' WHERE "xid" = ' + cIdz + ';' cQuery := HB_STRTOUTF8( cQuery, "RU1251" ) // на сервер PgSql всегда делаем // вывести в журнал отладку cMsg := " Запись №: " + cIdz + CRLF res := PQping( M->cPubPgConnInfo ) // проверка доступности сервера IF res == PQPING_OK PQexec( oServer:pDB, "BEGIN" ) // oServer:StartTransaction() res := PQexec( oServer:pDB, cQuery ) nResultStatus := PQresultStatus( res ) M->oServer:cError := PQresultErrorMessage( res ) IF nResultStatus == PGRES_COMMAND_OK cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + CRLF + CRLF //WaitWindowOk(cMsg + CRLF) cErr := "Добавление строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос: " + HB_UTF8TOSTR( cQuery ) //HB_MemoWrit( ChangeFileExt( cFile, ".ok" ), cErr ) ELSE cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + " - " cMsg += GetResultStatus( nResultStatus, 3 ) + CRLF + CRLF WaitWindowError(cMsg + CRLF) cErr := "Ошибка добавления строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос, вызвавший ошибку: " + HB_UTF8TOSTR( cQuery ) HB_MemoWrit( ChangeFileExt( cFile, ".err" ), cErr ) ENDIF PQexec( oServer:pDB, "END" ) lRet := .t. ELSE lRet := .f. cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz) + " не проведена !" ? cMsg WaitWindowError(cMsg) // вывести в журнал отладку cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz)+" не проведена !" cMsg += " -> Oператор: " + HB_NtoS(M->nOperat) ENDIF[/pre2]

Vlad04: Andrey Блин, что за SQL такая непростая штука... Чтобы записать в базу несколько полей Харбоур на SQL и не ориентирован. Вот пример запроса на обновление, на отбор данных. Строится с помощью построителя Обновление PARAMETERS SourceId Long, DestId Long; INSERT INTO DocAdd ( KOD, SCHET1, SCHET2, AmortSum, Skl, KOL2, Norma, BalSt, OBECT1, golov, id ) SELECT DocAdd.KOD, DocAdd.SCHET1, DocAdd.SCHET2, DocAdd.NDS, DocAdd.Skl, DocAdd.KOL, DocAdd.Price, DocAdd.SUMMA, DocAdd.OBECT1, DocAdd.golov, [DestId] AS Выражение1 FROM DocAdd WHERE (((DocAdd.id)=[SourceId])); ВЫборка SELECT treb.SCHET1, Sum(treb.SUMMA) AS Summa, treb.SCHET2, Org.REMNAME AS Org FROM PubVar, Org INNER JOIN treb ON Org.NPP = treb.Org2 WHERE (((treb.SCHET1) Like [PubVar].[Sch]) AND ((treb.SCHET2) Like [PubVar].[SchK]) AND ((treb.DATA) Between [PubVar].[NData] And [PubVar].[EData])) GROUP BY treb.SCHET1, treb.SCHET2, Org.REMNAME;

SergKis: Andrey пишет целые простыни писать приходиться.... кто мешает сделать как то так [pre2] Func SqlData( dD, cT ) Local cRet := "NULL" If empty(dD); RETURN cRet EndIf cRet := TRANSFORM( DTOS(dD),"@R 9999-99-99" ) If !Empty(cT); cRet += TRANSFORM(cT,"@R 99:99") + ":00'" EndIf RETURN cRet для др. типов данных так же сделать преобразовани для команды sql Func SqlExec( cQuery, cMsg ) Local ... // сам определишь res := PQping( M->cPubPgConnInfo ) // проверка доступности сервера IF res == PQPING_OK PQexec( oServer:pDB, "BEGIN" ) // oServer:StartTransaction() res := PQexec( oServer:pDB, cQuery ) nResultStatus := PQresultStatus( res ) M->oServer:cError := PQresultErrorMessage( res ) IF nResultStatus == PGRES_COMMAND_OK cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + CRLF + CRLF //WaitWindowOk(cMsg + CRLF) cErr := "Добавление строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос: " + HB_UTF8TOSTR( cQuery ) //HB_MemoWrit( ChangeFileExt( cFile, ".ok" ), cErr ) ELSE cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + " - " cMsg += GetResultStatus( nResultStatus, 3 ) + CRLF + CRLF WaitWindowError(cMsg + CRLF) cErr := "Ошибка добавления строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос, вызвавший ошибку: " + HB_UTF8TOSTR( cQuery ) HB_MemoWrit( ChangeFileExt( cFile, ".err" ), cErr ) ENDIF PQexec( oServer:pDB, "END" ) lRet := .t. ELSE lRet := .f. cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz) + " не проведена !" ? cMsg WaitWindowError(cMsg) // вывести в журнал отладку cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz)+" не проведена !" cMsg += " -> Oператор: " + HB_NtoS(M->nOperat) ENDIF Retrun и твой набор команд сократиться. Еще делаем шаблоны sql команд и hash с блоками кодов для получения значений полей табл.: hBlock := {"^01" => {|| ...}, ; "^02" => {|| ...}, ; ... ; } cMaska := '"cnza"=^01, "dtza"=^02, "kmaster"=^03, "qadres"=^04, "qdop"=^05, "qoborud"=^06, "qneispr"=^07, "qsrokza"=^08, "qoperat"=^09, "qvipza"=^10, "kdate"=^11, "kvipza"=^12, "datesrok"=^13, "datepere"=^13, "rem"=^15' aDim := HB_ATokens( cMaska, ',') aOut := {} For i := 1 To len(aDim) a := HB_ATokens(aDim[ i ], "=") b := hb_HGetDef(nBlock, a[ i ][2], Nil) If hb_IsBlock(b) s := EVal(b) // возврат всегда строка If len(s) > 0; AAdd(aOut, a[ i ][1]+"="+s // есть резултат (длина > 0) EndIf EndIf Next cQuery := 'UPDATE test SET ' k := len(aOut) For i := 1 To k; cQuery += aOut[ i ] + iif( i < k, ", ", "" ) Next ? cQuery [/pre2] Это схема, а не отлаженный код.

Andrey: SergKis пишет: кто мешает сделать как то так Да я только начал с синтаксисом разбираться. Идея отличная. Буду впоследствии так и делать. Спасибо !

Vlad04: Буду впоследствии так и делать. Лучше в построителе строить запрос с ПАРАМЕТРАМИ. Они (построители) для Postgres то же есть. Строишь запрос, проверяешь , а потом одну (всего одну строку) , возможно длинную, копируешь в свою программу. Добавляешь передачу параметров и все ок

Andrey: Vlad04 пишет: Лучше в построителе строить запрос с ПАРАМЕТРАМИ. Они (построители) для Postgres то же есть. Я его ещё в глаза не видел. Где его смотреть ?

SergKis: Vlad04 пишет Лучше в построителе строить С формы ввода (изменено несколько Getbox данных) перегонять на сервер всю запись, можно, но ... можно гнать только реально измененные значения, создав sql команду на лету (как показано выше)

Vlad04: Andrey Я его ещё в глаза не видел. Самый доступный посмотреть, это в MSACCESS. Для Postgres то же есть, поищи в Интернете. SergKis Да все возможно.Это хорошо, когда есть варианты.

Andrey: Запускаю свою прогу на МиниГуи + PgSql на ХР (libpq.dll от версии 9.5 и соответственно libpq.lib этой версии) Требует intl.dll при запуске. Добавил его и ещё libeay32.dll + ssleay32.dll Далее требует msvcr120.dll Нашёл сайте Майкрософт vcredist_x86.exe 2012 года Поддерживаемая операционная система Windows 7 Service Pack 1; Windows 8; Windows 8.1; Windows Server 2003; Windows Server 2008 R2 SP1; Windows Server 2008 Service Pack 2; Windows Server 2012; Windows Vista Service Pack 2; Windows XP Установил его в ХР, всё равно не работает программа, не запускается !!! Под 7-кой приложение нормально запускается. Вопрос: как запустить под ХР ????

Pasha: Наверное, надо установить msvc runtime соответствующей версии. Какой - не знаю. Выдал у себя команду: dir/s msvcr*.dll >e:\msv.txt нашлось много чего: Содержимое папки C:\Windows\System32 01.10.2012 21:30 829 264 msvcr100.dll 11.09.2013 19:39 18 000 msvcr100_clr0400.dll 05.11.2012 23:26 849 360 msvcr110.dll 11.09.2013 19:39 855 664 msvcr110_clr0400.dll 24.07.2014 23:47 869 544 msvcr120_clr0400.dll 16.12.2011 11:46 634 880 msvcrt.dll 6 файлов 4 056 712 байт Содержимое папки C:\Windows\SysWOW64 13.06.2014 10:23 773 968 msvcr100.dll 11.09.2013 21:21 18 000 msvcr100_clr0400.dll 06.11.2012 02:20 875 472 msvcr110.dll 11.09.2013 21:21 863 344 msvcr110_clr0400.dll 25.07.2014 02:35 875 688 msvcr120_clr0400.dll 18.03.2002 16:01 344 064 msvcr70.dll 21.02.2003 15:42 348 160 msvcr71.dll 16.12.2011 10:52 690 688 msvcrt.dll 14.07.2009 04:15 253 952 msvcrt20.dll 14.07.2009 04:07 60 928 msvcrt40.dll 10 файлов 5 104 264 байт это все для разных версий msvc, многие продукты требуют для работы свою версию. Ну и традиционное общее замечание: Невозможно писать программу на "МиниГуи + PgSql" Можно писать на Harbour + bcc или скажем mingw, и использовать какие-то дополнительные библиотеки, те же minugui и hbpqsql.

Dima: Andrey Отсюда бери https://rutracker.org/forum/viewtopic.php?t=4594892

Andrey: Pasha пишет: Наверное, надо установить msvc runtime соответствующей версии. Какой - не знаю. Это точно так. Я понял, что здесь собака и зарыта. Методом проб и ошибок нашёл что нужно для XP чтобы прога "Harbour + bcc + minugui + hbpqsql" заработала. Нужно в систему ставить Microsoft Visual C++ 2013 Redistributable (x86) 12.0.30501 - 6,3Mb всего. После этого прога в ХР заработала.... Блин и как теперь можно сделать замену этого малопонятного окна у себя в программе ?

Петр: Andrey пишет: Блин и как теперь можно сделать замену этого малопонятного окна у себя в программе ? Чтоб сделать замену именно этого придется немало поучиться С другой стороны ничто не мешает проверить наличие установленной версии MS runtime Примерно во так как здесь Detect if Visual C++ Redistributable for Visual Studio 2013 is installed

SergKis: Andrey перепиши все нужные dll из vc к своему exe и так устанавливай. А что у кого (версии ms) стоит\нет - не всегда поможет решить проблемму, то админа нет, то прав и т.д.

Andrey: Петр пишет: С другой стороны ничто не мешает проверить наличие установленной версии MS runtime Да делал такое уже один раз в своём почтовике. Ехе-ник проверял Redistributable for Visual Studio 2008 если нет, то давал возможность ставить его по ссылке с сайта, а если есть, то выгружал из своих ресурсов второй ехе-ник, уже отправляющий почту. Люблю проги из одного ехе-ника ! Девиз: всё своё ношу с собой !

Andrey: Для работы PostgreSql на МиниГуи в проект добавляю следующие библиотеки: [pre2]# extension *.Lib PostgreSQL -lhbpgsql -llibpq[/pre2] Для работы ехе-ника необходимы 4 dll-ки: libpq.dll (версии 9.5) intl.dll libeay32.dll ssleay32.dll Можно как то отказаться от intl.dll чтобы далее не требовалась msvcr120.dll, т.е. обойтись без Microsoft Visual C++ 2013 Redistributable (x86) 12.0.30501 ?

Петр: Chapter 16. Installation from Source Code 16.7.4. MinGW/Native Windows

Andrey: Всем привет ! Имею такой код отправки на сервер: [pre2] res := PQping( M->cPubPgConnInfo ) // проверка доступности сервера IF res == PQPING_OK PQexec( oServer:pDB, "BEGIN" ) // oServer:StartTransaction() res := PQexec( oServer:pDB, cQuery ) nResultStatus := PQresultStatus( res ) // строка 657 M->oServer:cError := PQresultErrorMessage( res ) IF nResultStatus == PGRES_COMMAND_OK cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + CRLF + CRLF //WaitWindowOk(cMsg + CRLF) cErr := "Добавление строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос: " + HB_UTF8TOSTR( cQuery ) //HB_MemoWrit( ChangeFileExt( cFile, ".ok" ), cErr ) ELSE cMsg += "Результат: " + GetResultStatus( nResultStatus, 2 ) + " - " cMsg += GetResultStatus( nResultStatus, 3 ) + CRLF + CRLF WaitWindowError(cMsg + CRLF) cErr := "Ошибка добавления строки: " + HB_UTF8TOSTR( oServer:ErrorMsg() ) + CRLF + CRLF cErr += "Запрос, вызвавший ошибку: " + HB_UTF8TOSTR( cQuery ) HB_MemoWrit( ChangeFileExt( cFile, ".err" ), cErr ) ENDIF PQexec( oServer:pDB, "END" ) lRet := .t. ELSE lRet := .f. cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz) + " не проведена !" ? cMsg WaitWindowError(cMsg) // вывести в журнал отладку cMsg := "Ошибка сервера: " + GetPingResult( res ) cMsg += CRLF + "Запись с XID="+HB_NtoS(nIdz)+" не проведена !" [/pre2] Периодически у ОДНОГО заказчика (другие не жаловались) вылетает прога с такой ошибкой: Судя по коду - ошибка в С-функции... Как исправить это ? Почему только у одного заказчика вылетает ( Операционка Win7) ?

Петр: Andrey пишет: Как исправить это ? все функции проверять на код возврата, тогда и вопросов меньше будет. Andrey пишет: Почему только у одного заказчика вылетает Странно, что у всех работает У этого банально может сеть глючить. Andrey пишет: Судя по коду - ошибка в С-функции... там же написано - неверный аргумент. все функции проверять на код возврата, по возможности применять async api



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