OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 17 Ноябрь, 2019 22:35

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Суббота, 26 Май, 2012 21:02 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Доброго времени суток. Я начинаю осваивать BlackBox. Мой интерес -
использование среды для разработки клиентских приложений, работающих
с различными СУБД. (Возможно с разработкой "прямого" доступа к серверу
без установки клиента на ПК пользователя).
Но сейчас застопорился с выполнение такого запроса:
WITH RECURSIVE temp1 ( "empno","mgr","ename","job","hiredate","sal","comm","deptno",LEVEL ) AS (
SELECT T1."empno",T1."mgr", T1."ename", T1."job",T1."hiredate", T1."sal",T1."comm",T1."deptno", 1
FROM EMP T1 WHERE T1."mgr" IS NULL
union
select T2."empno",T2."mgr", T2."ename", T2."job",T2."hiredate", T2."sal",T2."comm",T2."deptno",LEVEL + 1
FROM EMP T2 INNER JOIN temp1 ON( temp1."empno"= T2."mgr") )
select * from temp1 ORDER BY LEVEL LIMIT 100

Обращение идет к СУБД PostgreSQL через драйве ODBC (в ББ SqlOdbc3)
при этом возвращается пустой набор
Тот же запрос в Delphi (здесь большой опыт) через тот же драйвер ODBC получается правильный (не пустой ) набор
Помогите пожалуйста в моей проблеме - дальнейшие шаги и т.п.
Спасибо всем кто откликнется


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 26 Май, 2012 22:21 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Попробуйте для начала самым простым способом поглядеть результат.
Код:
MODULE PrivTest;

   IMPORT Log, SqlDB;
   
   PROCEDURE Do* (IN statement: ARRAY OF CHAR);
      VAR
         res: INTEGER; db: SqlDB.Database; tab: SqlDB.Table;
         row: SqlDB.Row; i, j: INTEGER;
   BEGIN
      SqlDB.OpenDatabase("driver", "id", "password", "database", SqlDB.sync, SqlDB.showErrors, db, res);
      ASSERT(res = 0, 0);
      tab := db.NewTable();
      ASSERT(tab # NIL, 0);
      tab.Exec(statement);
      ASSERT(tab.res = 0, 0);
      ASSERT(tab.columns > 0, 0);
      i := 0; tab.Read(i, row);
      WHILE tab.res # SqlDB.noData DO
         j := 0;
         WHILE j < tab.columns DO
            Log.String(row.fields[j]); Log.Tab;
            INC(j)
         END;
         Log.Ln;
         INC(i); tab.Read(i, row)
      END
   END Do;

   PROCEDURE Do1*;
   BEGIN
      Do('xxxx')   (* — в коде можно любую цепочку указать *)
   END Do1;
   
END PrivTest.

^Q PrivTest.Do1

^Q "PrivTest.Do('xxxx')" — тут только без кавычек

Чтобы передать параметр с кавычками, можно исп-ть
^Q  ert0devCommanders.ReadStrAndDo('PrivTest.Do') xxxx ~
Если ASSERT какой сработает, смотрите в документации постусловия соотв. процедуры.

Другие запросы результат дают?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 09:02 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Добрый день!
Спасибо за быстрый ответ!
Попробовал запустить Ваш пример и получил 1 в res = noDriverMod
Т.е. здесь проблема в указании параметров драйвера, но какие я пока не знаю.
И где это можно найти пока тоже
Остальные запросы у меня проходили при таком же варианте параметров
SqlDB.OpenDatabase("SqlOdbc3", "", "TIGER", "PostgreSQL30a", FALSE, TRUE, db, res);
, но не содержали кавычек и не было union
и прочих "вкусностей"


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 10:52 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Отладочный журнал ODBC включать пробовали?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 11:16 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
oddfish49 писал(а):
Попробовал запустить Ваш пример и получил 1 в res = noDriverMod
Т.е. здесь проблема в указании параметров драйвера, но какие я пока не знаю.
Вы прописали в примере SqlDB.OpenDatabase("SqlOdbc3", "", "TIGER", "PostgreSQL30a", SqlDB.sync, SqlDB.showErrors, db, res) и получили noDriverMod? Странно...

oddfish49 писал(а):
, но не содержали кавычек и не было union
и прочих "вкусностей"
Насколько я знаю
1) Запрос перерабатывает только SqlDB, выполняя подстановку значений переменных.
SqlDB Docu писал(а):
For example, if there is a global and exported integer variable searchId in module Sample, the following SQL statement can be used:

"SELECT * FROM Companies WHERE id = :Sample.searchId"

SqlDB provides a procedure to execute such a string (SqlDB.Database.Exec, SqlDB.Table.Exec). These procedures replace all placeholders starting with a colon by the appropriate run-time values.
Теоретически запрос может портится тут, если что не так. Драйвера к тексту (синтаксису и пр) запроса отношения не имеют.
2) У хитрого запроса может какая специфика есть при получении результата через ODBC? Вдруг версия ODBC в очередной раз увеличилась и ODBC-драйвер использует фичи, на которые SqlOdbc3 не рассчитан.
Код:
MODULE SqlOdbc3;
...
   (* The major problem with ODBC is that many of its functions, or many uses of them, are optional.
      This means that one can never rely on a function to be really implemented by the current ODBC driver.
      As a result, one often has to try the best approach first, then back off if necessary to the next best, etc.
      This is cumbersome and difficult to test exhaustively. *)
Попробуйте выставить перед работой SqlDB.debug := TRUE; SqlOdbc3.debug := TRUE, может чего удастся выяснить.
Код:
MODULE SqlOdbc3;
...
  debug*: BOOLEAN;   (* if TRUE, show more information about what's happening *)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 12:04 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
В PrivTest не выполняется простейший запрос select * from emp -
вылезает та же ошибка - чего-то не хватает в id (я так думаю)
В Примере SQL Browser выполняется и этот запрос и запрос на связку таблиц EMP и DEPT


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 13:42 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
oddfish49 писал(а):
В PrivTest не выполняется простейший запрос select * from emp -
вылезает та же ошибка - чего-то не хватает в id (я так думаю)
noDriverMod --- ББ не может загрузить модуль драйвера. Проверьте как Вы имя указали, больше не знаю что предположить. Разве что параметры местами перепутал, так вроде нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 13:43 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Может быть, неполная подсистема Sql? Или скопированная из другой версии ББ?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 15:11 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Все делается в сборке blackbox15i21base


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 15:13 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Вот вызов SqlDB.OpenDatabase("SqlOdbc3", "", "TIGER", "PostgreSQL30a", FALSE, TRUE, db, res);
res = 1 и в сборке BlackBox.AD (к книге Вирта)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 15:54 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Добился что простой селект выполняется с нормальным результатом (PrivTest)
Пустой лог при выполнении объединения РЕЗУЛЬТАТА НЕТ, НО ОШИБОК ТОЖЕ НЕТ!
Наличие кавычек вокруг полей не влияет на результат


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 17:06 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Надо смотреть, что из ББ летит в ODBC, и что попадает в итоге в сервер. Включайте все логи, какие только возможно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 19:58 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
это из psqlodbc_8120.log

[0.003]conn = 65C728C8, PGAPI_Connect(DSN='PostgreSQL30a', UID='SCOTT', PWD='xxxxx')
[0.012]Driver Version='09.01.0100,201112290002' linking 1500 static Multithread library
[0.020]Global Options: fetch=100, socket=4096, unknown_sizes=0, max_varchar_size=255, max_longvarchar_size=8190
[0.026] disable_optimizer=0, ksqo=1, unique_index=1, use_declarefetch=0
[0.030] text_as_longvarchar=1, unknowns_as_longvarchar=0, bools_as_char=1 NAMEDATALEN=64
[0.035] extra_systable_prefixes='dd_;', conn_settings='' conn_encoding=''
[0.321] [ PostgreSQL version string = '9.1.3' ]
[0.322] [ PostgreSQL version number = '9.1' ]
[0.340]conn=65C728C8, query='select oid, typbasetype from pg_type where typname = 'lo''
[0.360] [ fetched 0 rows ]
[0.371] [ Large Object oid = -999 ]
[0.374]conn=65C728C8, query='set client_encoding to 'WIN1251''
[0.482]conn=65C728C8, query='WITH RECURSIVE temp1 ( "empno","mgr","ename","job","hiredate","sal","comm","deptno",LEVEL ) AS (SELECT T1."empno",T1."mgr", T1."ename", T1."job",T1."hiredate", T1."sal",T1."comm",T1."deptno", 1 FROM EMP T1 WHERE T1."mgr" IS NULL union select T2."empno",T2."mgr", T2."ename", T2."job",T2."hiredate", T2."sal",T2."comm",T2."deptno",LEVEL + 1 FROM EMP T2 INNER JOIN temp1 ON( temp1."empno"= T2."mgr") )select * from temp1 ORDER BY LEVEL LIMIT 100'
[0.623] [ fetched 14 rows ]
[0.650]STATEMENT ERROR: func=PGAPI_ExtendedFetch, desc='', errnum=31, errmsg='The fetch type for PGAPI_ExtendedFetch isn't allowed with ForwardOnly cursor.'
[0.656] ------------------------------------------------------------
[0.658] hdbc=65C728C8, stmt=65C77A28, result=65C78E70
[0.659] prepare=3, internal=0
[0.660] bindings=65C7FB60, bindings_allocated=9
[0.661] parameters=00000000, parameters_allocated=0
[0.662] statement_type=4, statement='WITH RECURSIVE temp1 ( "empno","mgr","ename","job","hiredate","sal","comm","deptno",LEVEL ) AS (SELECT T1."empno",T1."mgr", T1."ename", T1."job",T1."hiredate", T1."sal",T1."comm",T1."deptno", 1 FROM EMP T1 WHERE T1."mgr" IS NULL union select T2."empno",T2."mgr", T2."ename", T2."job",T2."hiredate", T2."sal",T2."comm",T2."deptno",LEVEL + 1 FROM EMP T2 INNER JOIN temp1 ON( temp1."empno"= T2."mgr") )select * from temp1 ORDER BY LEVEL LIMIT 100'
[0.671] stmt_with_params='WITH RECURSIVE temp1 ( "empno","mgr","ename","job","hiredate","sal","comm","deptno",LEVEL ) AS (SELECT T1."empno",T1."mgr", T1."ename", T1."job",T1."hiredate", T1."sal",T1."comm",T1."deptno", 1 FROM EMP T1 WHERE T1."mgr" IS NULL union select T2."empno",T2."mgr", T2."ename", T2."job",T2."hiredate", T2."sal",T2."comm",T2."deptno",LEVEL + 1 FROM EMP T2 INNER JOIN temp1 ON( temp1."empno"= T2."mgr") )select * from temp1 ORDER BY LEVEL LIMIT 100'
[0.680] data_at_exec=-1, current_exec_param=-1, put_data=0
[0.681] currTuple=-1, current_col=-1, lobj_fd=-1
[0.682] maxRows=0, rowset_size=1, keyset_size=0, cursor_type=0, scroll_concurrency=1
[0.684] cursor_name='SQL_CUR65C77A28'
[0.685] ----------------QResult Info -------------------------------
[0.686] fields=65C77A08, backend_tuples=65C790C8, tupleField=1707577544, conn=65C728C8
[0.688] fetch_count=0, num_total_rows=14, num_fields=9, cursor='(NULL)'
[0.690] message='(NULL)', command='SELECT 14', notice='(NULL)'
[0.691] status=100, inTuples=0
[0.692]CONN ERROR: func=PGAPI_ExtendedFetch, desc='', errnum=0, errmsg='(NULL)'
[0.695] ------------------------------------------------------------
[0.696] henv=65C71280, conn=65C728C8, status=1, num_stmts=16
[0.698] sock=65C75430, stmts=65C77510, lobj_type=-999
[0.699] ---------------- Socket Info -------------------------------
[0.700] socket=600, reverse=0, errornumber=0, errormsg='(NULL)'
[0.702] buffer_in=1707562240, buffer_out=1707566344
[0.703] buffer_filled_in=1425, buffer_filled_out=0, buffer_read_in=1425

а файл mylog_8120.log в аттаче


Вложения:
Комментарий к файлу: mylog_8120.log
mylog_8120_log.txt [40.39 КБ]
Скачиваний: 433
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 20:50 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Попробуйте для порядку в каком-нибудь 1.6 rc-6.
http://oberoncore.ru/blackbox/1.6-rc6 или http://oberoncore.ru/projects/bb16base-core

oddfish49 писал(а):
[0.650]STATEMENT ERROR: func=PGAPI_ExtendedFetch, desc='', errnum=31, errmsg='The fetch type for PGAPI_ExtendedFetch isn't allowed with ForwardOnly cursor.'
Но учитывая это, вполне может оказаться верным предположение, что хитрый запрос требует какого-то особого способа извлечения данных, на которые драйвер не рассчитан. Тогда придётся разобраться и допилить драйвер для себя в рассчёте на эту "фичу".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 21:43 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Спасибо Евгений!
От версии ББ не зависит.
Нюансы ODBC и реализаций
Я много лет разрабатывал программные проекты с использованием Oracle (SQL и PL/SQL), Delphi и ODAC (Devart)
и несколько раз делал попытки уйти от проприетарного ПО но пока безуспешно. Эта попытка - последняя...
---
Скорее всего последнее.
К сожалению в PostgreSQL плохо документирован ODBC драйвер
Такая же ошибка встречается еще несколько раз, но по другому поводу
Будем рыть. Еще раз спасибо.
Кстати и к большому сожалению это свойственно открытому ПО


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 22:04 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
Ещё и проблема самого стандарта ODBC (см. комментарии от оминк в исходнике). Насколько я понимаю её суть, сделать универсальный ББ-драйвер для произвольного (и вроде как стандартного) ODBC-драйвера проблематично.

Есть такой вариант: если у PostgreSQL есть C-API или какой-ещё апи, который можно будет из ББ напрямую вызывать, то можно сделать ББ-драйвер, который будет работать с этой СУБД напрямую. И это может оказаться в итоге проще, нежели разбирать нюансы ODBC и проч.

Заготовка драйвера SqlObxDriv.
Sql Dev-Man писал(а):
SqlDrivers
File Sql/Mod/ObxDriv contains a template of a new Sql driver. Its empty parts can be filled out to create a new driver for a database not yet supported by Sql, or to avoid the use of ODBC.
Например, Иван Кузьмицкий сделал драйвер для MySQL (http://oberoncore.ru/bbcc/subs/mysql/), Владимир Сидоров для Firebird (http://oberoncore.ru/bbcc/subs/fib/)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 27 Май, 2012 22:44 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Евгений Темиргалеев писал(а):
Есть такой вариант: если у PostgreSQL есть C-API или какой-ещё апи, который можно будет из ББ напрямую вызывать, то можно сделать ББ-драйвер, который будет работать с этой СУБД напрямую. И это может оказаться в итоге проще, нежели разбирать нюансы ODBC и проч.
Совершенно верно, и драйвер, к тому же, упростил процедуру подключения к БД. Мы отказались от использования ODBC уже давно и не жалеем об этом.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 28 Май, 2012 07:53 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Большое спасибо за дельные советы и предложения
Собственно именно прямое соединение и желательно
т.к. настраивать odbc на каждой клиентской машине -
очень утомительно. Просто хотелось немного пощупать
оба продукта прежде чем глубоко лезть вовнутрь
Еще раз спасибо


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 23 Июнь, 2012 13:36 

Зарегистрирован: Воскресенье, 13 Май, 2012 14:14
Сообщения: 13
Добрый день!
Может быть кому-то пригодится :D
Как оказалось это древняя проблема ODBC драйвера Postgres
Решается в данном случае совсем просто -

dlg.statement := 'SELECT * FROM (WITH RECURSIVE temp1 ( "empno","mgr","ename","job","hiredate","sal","comm","deptno",LEVEL ) AS (SELECT T1."empno",T1."mgr", T1."ename", T1."job",T1."hiredate", T1."sal",T1."comm",T1."deptno", 1 FROM EMP T1 WHERE T1."mgr" IS NULL union select T2."empno",T2."mgr", T2."ename", T2."job",T2."hiredate", T2."sal",T2."comm",T2."deptno",LEVEL + 1 FROM EMP T2 INNER JOIN temp1 ON( temp1."empno"= T2."mgr") )select * from temp1 ORDER BY LEVEL LIMIT 100) ttt';

т.е. запрос обрамляется одним простейшим select-ом


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 23 Июнь, 2012 22:05 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4525
Откуда: Россия, Орёл
oddfish49 писал(а):
Как оказалось это древняя проблема ODBC драйвера Postgres
Решается в данном случае совсем просто -... т.е. запрос обрамляется одним простейшим select-ом
А как же Ваше замечание насчёт делфи в первом сообщении? Выходит там этот костыль встроен?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB