FB через gds32.dll

ЧАстые Вопросы и Ответы

Модераторы: kdv, CyberMax

Ответить
Гюли
Сообщения: 5
Зарегистрирован: 17 май 2006, 18:14

FB через gds32.dll

Сообщение Гюли » 17 май 2006, 18:18

Добрый день! Надо работать с базой FireBird через gds32.dll. Все необходимые файлы содержатся в директории откуда вызывается приложение:intl\fbintl.dll, udf\fbudf.dll, udf\ib_udf.dll, gds32.dll, ib_util.dll, aliases.conf, firebird.conf и firebird.msg. Есть таблица INVOICES содержащая перечень счетов. В общем я открываю эту базу без проблем, создаю транзакцию тоже без проблем, читаю данные из этой таблицы тоже без проблем если в переданном запросе не выбрано поле типа DATE. Как только я добавляю в запрос чтобы выводилось поле с этим типом, так сразу на стадии подготовки вылетает с ошибкой. Та же ошибка, если я ставлю * (звездочку).
Короче, "SELECT DOC_DI,DOC_NO FROM INVOICES" - отрабатывает отлично! А вот "SELECT DOC_DI,DOC_NO,DOC_DATE FROM INVOICES" - завершается с ошибкой. С названиями полей все нормально, ошибок нет! Еще, например, я так же могу выполнять запросы на изменения типа "UPDATE INVOICES SET DOC_NO='12345' WHERE DOC_ID=54321", но как только я добавляю в запрос операции опять же с этим полем типа DATE, то запрос не выполняется и возвращается ошибка, например: "UPDATE INVOICES SET DOC_NO='12345' WHERE DOC_DATE='1.1.2006'". Дату передавать я уже пробовал и как '1/1/2006' и #1/1/2006#(даже такое в интернете встречал). И обратные порядки пробовал, но все время возвращается ошибка код которой соответствует "Dynamic SQL error.". Может кто работал с FB на низком уровне, кто подскажет как быть с этим типом поля. А надо работать именно так, через gds32.dll. Заранее спасибо всем!

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 май 2006, 18:23

Уважаемый Гюли!
Вы уже отправили аналогичный вопрос на support# ibase.ru.
В следующий раз прошу избегать кросспостов.

Гюли
Сообщения: 5
Зарегистрирован: 17 май 2006, 18:14

Сообщение Гюли » 17 май 2006, 18:33

Приношу свои извинения, kdv, т.к. не знал, что этот форум и support# ibase.ru почти одно и то же. Просто пытался расширить диапазон. Все понял! Жду ответа! Заранее спасибо!

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 17 май 2006, 19:34

как бы, и то и другое - ibase.ru.
запрос не выполняется и возвращается ошибка, например: "UPDATE INVOICES SET DOC_NO='12345' WHERE DOC_DATE='1.1.2006'"
какая именно ошибка? тут все нормально должно работать.

Гюли
Сообщения: 5
Зарегистрирован: 17 май 2006, 18:14

Код ошибки.

Сообщение Гюли » 18 май 2006, 10:20

Ошибка - 140000F9h (335544569 дес.) - в iberror.h эта ошибка описана как isc_dsql_error. При формировании сообщения об ошибке через ф-цию isc_interprete выдает строку "Dynamic SQL Error". Причем на select, update и insert одна и таже ошибка, как только начинаю использовать поля типа DATE. Я еще пытался использовать CAST('1.1.2006' AS DATE) вместо '1.1.2006'. В этом случае выдается ошибка - 14000074h (335544436 дес.) - в iberror.h эта ошибка описана как isc_sqlerr. При формировании сообщения об ошибке через ф-цию isc_interprete выдает строку "SQL error code =-206". Я было подумал - может это файл базы данных в каком-то формате может с другой версией был создан. Попытался сам создать базу через API gds32.dll, создать в ней таблицу с полем типа DATE и создать запись в ней со значением поля типа DATE равным '1.1.2006'. Вот запросы:
CREATE DATABASE 'TMPBASE.FDB' USER 'SYSDBA' PASSWORD 'masterkey' PAGE_SIZE=2048
CREATE TABLE TMP_TAB(TMP_DATE DATE)
INSERT INTO TMP_TAB(TMP_DATE)VALUES('1.1.2006')
Все запросы вызывал через ф-цию isc_dsql_execute_immediate. Первые два вызова отрабатывают без ошибок. Третий вызывает вышеописанную ошибку даже в созданной базе и таблице через эту gds32.dll. Если меняю второй запрос на создание поля не типа DATE, а, например, VARCHAR(10), то все проходит замечательно, без ошибок!
Раз Вы говорите, что ошибок не должно быть и мой запрос составлен правильно, я имею в виду формат передачи строки с датой, то может быть что-то с gds32.dll? Но в то же время программа, написанная на делфи, которая работает с этой же базой с которой мне надо работать через эту же gds32.dll работает нормально! Я просто думаю, что может быть при открытии базы и/или транзакции я не проставляю какие-то параметры, может версию какую не ту указываю? Но, вроде, все как в исходниках на примерах показано я делаю! Версию при открытии использую SQLDA_VERSION1.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 18 май 2006, 11:19

Гюли, ошибку надо интерпретировать целиком (вызывать isc_interprete пока не вернет 0). Там помимо главного кода идет еще очень много доп.информации.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 18 май 2006, 12:11

я бы еще поинтересовался, с каким диалектом вызываются prepare/execute...

Гюли
Сообщения: 5
Зарегистрирован: 17 май 2006, 18:14

Дополненное до конца сообщение об ошибке.

Сообщение Гюли » 18 май 2006, 12:21

Опля, после выемки до конца всего сообщения об ошибке стало еще интереснее!
Сообщение следующее как для "INSERT INTO INVOICES(DOC_DATE)VALUES('1.1.2006')" так и для "INSERT INTO INVOICES(DOC_DATE)VALUES(CAST('1.1.2006' AS DATE))":
"Dynamic SQL Error
SQL error code=-206
Column unknown
DOC_DATE
Client SQL dialect 1 does not support reference to DATE datatype"

И еще! Я снова пробовал создавать базу, таблицу с полем типа DATE и затем добавить запись с датой, но перед инсертом провести фиксацию транзакции, и в этом случае все прошло без ошибок! Эта моя догадка о том, что объект, над которым я провожу манипуляцию, должен уже существовать в базе данных как постоянный, подтвержается?

Теперь на основе этих двух фактов - полное описание ошибки и отсутствие ошибки во втором случае можно полагать, что мне как-то надо особенно, что ли, открыть существующую базу? Ведь, как я понимаю из сообщения, диалект (или версия) 1 не поддерживает ссылки на тип данных DATE?

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 18 май 2006, 14:09

У isc_dsql_execute_immediate() есть шестой по счету параметр, называемый dialect. Он должен иметь значение соответствующее диалекту базы. Желательно 3.
В ошибке тебе же черным по белому сказали что тип DATE не работает с первым диалектом. И даже сказали где этот диалект указан: на клиенте. Т.е. при вызове функции.

Гюли
Сообщения: 5
Зарегистрирован: 17 май 2006, 18:14

Диалект/Версия.

Сообщение Гюли » 18 май 2006, 14:27

В общем поменял везде SQLDA_VERSION1 на SQL_DIALECT_CURRENT, который равен SQL_DIALECT_V6 в хедере gds.h. Сначала тоже ошибку выдавало, но потом вернул обратно на SQLDA_VERSION1 при заполнении структуры XSQLDA. Запросы с полем типа DATE и CAST(DOC_DATE AS VARCHAR(10)) стали работать в select, update и insert! Так что вопрос закрыт! Спасибо большое за поддержку!
А я как-то забыл что isc_interprete возвращает больше чем одну строку и написал процедуру по обработе ошибок с базой без учета этого момента. Оказалось, что будь я повнимательнее при написании этой процедуры обработки ошибок, то гораздо раньше бы навелся на мысль, что надо как-то с диалектом/версией работать в этом плане!
Еще раз большое спасибо за помощь!

Ответить