read-only database

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

read-only database

Сообщение FilSCool » 23 сен 2007, 17:12

Приветствую, господа!
Вопрос такой:
Пишу клиента на С++ используя Borland Builder. Сервер FireBird 2.0 (SS).
компоненты доступа к базе - с панели InterBase.
Использую:
TIBDatabase
TIBTransaction
TIBQuery
TDataSource
TDBGrid
+ TIBDatabaseInfo.

При попытке сделать IBQuery1->Edit() или IBQuery1->Insert() вылетает ошибка "cennot modify read-only database". (аналогично с любым DataSet).
IBDatabaseInfo1->ReadOnly возвращает "0".

Прописываю параметры IBDatabase1->Params вручную(на всякий...):
user_name=SYSDBA
password=password
lc_ctype=WIN1251
read_write
nowait
read_committed
rec_version

результат прежний.

Может, я не правильно прописываю? Как добиться редактируемости базы?

FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

Re: read-only database

Сообщение FilSCool » 23 сен 2007, 19:43

Ну что, господа, будут версии?

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

Сообщение Dimitry Sibiryakov » 24 сен 2007, 08:03

Ты уверен, что ошибка именно такая, а не "cannot modify read-only dataset"?

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

Сообщение kdv » 24 сен 2007, 10:30

Как добиться редактируемости базы?
прочитать, наконец, документацию.
если база в readonly, так выключи readonly.
и не пихай бред в параметры ibdatabase.

см.
www.ibase.ru/devinfo/ibx.htm

FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

Сообщение FilSCool » 24 сен 2007, 13:21

Dimitry Sibiryakov писал(а):Ты уверен, что ошибка именно такая, а не "cannot modify read-only dataset"?
Блин, торопился - описАлся. Именно "cannot modify read-only dataset"!
Прошу прощения.

kdv писал(а):прочитать, наконец, документацию.
www.ibase.ru/devinfo/ibx.htm
если база в readonly, так выключи readonly.
прочитал уже, и не раз. К cамой базе имею доступ на чтение/запись из программ управления БД(FlameRobin, Interbase&Firebird development Studio).
kdv писал(а): и не пихай бред в параметры ibdatabase.
Что значит "бред"? Что лишнего или неправильного?
изначально вообще ставил только
user_name=SYSDBA
lc_ctype=WIN1251

полагался на умолчания, которые не очень подходят. Но результат один.

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

Сообщение kdv » 24 сен 2007, 14:35

Что значит "бред"? Что лишнего или неправильного?
бред это запихивание параметров транзакции в параметры коннекта.
Именно "cannot modify read-only dataset"!
тогда ЕЩЕ РАЗ ЧИТАЙ статью.
прочитал уже, и не раз.
по диагонали читаешь ведь. в статье все написано. см. IBDataSet.

цитирую текст, которым начинается раздел по используемому тобой IBQuery:
"Компонент для выполнения запросов. Если не требуется выполнять "редактирование" записей запроса, то IBQuery можно использовать вместо IBDataSet. Или, как замену IBDataSet можно использовать комбинацию IBQuery + IBUpdateSQL."

и ты говоришь что "читал и не раз"?

FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

Сообщение FilSCool » 24 сен 2007, 16:44

kdv писал(а): цитирую текст, которым начинается раздел по используемому тобой IBQuery:
"Компонент для выполнения запросов. Если не требуется выполнять "редактирование" записей запроса, то IBQuery можно использовать вместо IBDataSet. Или, как замену IBDataSet можно использовать комбинацию IBQuery + IBUpdateSQL."
Хотите сказать из Query нельзя редактировать базу?
Так бред же, по-моему: зачем тогда наследуемые у dataset-а вункции перехода в режим вставки и редактирования?
Можно ли, например, редактировать?:

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

IBQuery1->Edit();
IBQuery1->FieldByName("Field1")->AsString= "aaaaaaa";
IBQuery1->Post();
Результат все тот же.

И почему нельзя так?:

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

IBDataSet1->InsertSQL->Clear();
IBDataSet1->InsertSQL->Add("insert into mybase (Field1)");
IBDataSet1->InsertSQL->Add("values (\'aaaa\')");
IBDataSet1->ExecSQL();
Теперь с TIBDataSet.

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

IBDataSet1->InsertSQL->Clear();
IBDataSet1->InsertSQL->Add("insert into mybase (Field1)");
IBDataSet1->InsertSQL->Add("values (\'aaaa\')");
IBDataSet1->ExecSQL();
Результат все тот же.
Попробовал через ParamByName - то же самое.

если несложно и можно, пришли, плиз, маленький примерчик с возможностью редактирования записей табл., чтобы увидеть воочию что-где прописано.

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

Сообщение kdv » 24 сен 2007, 17:35

Хотите сказать из Query нельзя редактировать базу?
Так бред же, по-моему: зачем тогда наследуемые у dataset-а функции перехода в режим вставки и редактирования?
в SQL базах данных данные редактируются тремя операторами - insert, update, delete. SELECT - это оператор ЧТЕНИЯ данных, соответственно он "редактироваться" никак не может. Если ты написал SELECT, и хочешь редактировать, значит или ты сам должен дописать необходимые для "редактирования" запросы, как это показано на примере IBDataSet в пресловутой статье, или чтобы эти запросы сформировала АВТОМАТИКА в компонентах, как это делалось раньше в BDE.
www.ibase.ru/devinfo/bde.htm

Именно поэтому, раз такой "автоматики" IBX нет, то "редактируемость" набора данных можно обеспечить только вручную. Т.е. или прописыванием нужных запросов IBDataSet, или конструированием аналога IBDataSet из IBQuery + IBUpdateSQL.
если несложно и можно, пришли, плиз, маленький примерчик с возможностью редактирования записей табл., чтобы увидеть воочию что-где прописано.
меня уже смех разбирает, если честно. :)
что ж ты, злыдень, не можешь прочитать
www.ibase.ru/devinfo/ibx.htm#ibdataset по человечески? :)

там же с картинками все объясняется.

p.s. и еще - не все SQL-операторы могут быть "редактируемыми". Элементарный пример - любой запрос с агрегатами. select id, count(*) from table group by id.

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

Сообщение kdv » 24 сен 2007, 17:44

могу еще цитатку из www.ibase.ru/devinfo/bde.htm подкинуть

"Живые" запросы

Если способность TTable редактировать и удалять записи ни у кого не вызывает удивления, то TQuery требует, чтобы свойство RequestLive было установлено в True. Если при False запрос отправлялся непосредственно на сервер, то при True запрос предварительно обрабатывается локальным SQL (модуль IDSQL32.DLL). Это необходимо для того, чтобы TQuery смог сформировать запросы INSERT/UPDATE/DELETE на основании заданного SELECT. Для TTable построение таких запросов не представляет сложности, т.к. задано только имя таблицы, имена полей считаны и т.п. А существующий SQL-запрос нужно синтаксически разобрать, чтобы понять, сколько в нем используется таблиц, какие выбираются поля и из каких таблиц, и можно ли вообще сформировать запросы на вставку, обновление и удаление данных.

Именно таким разбором SQL и занимается Local SQL. Разумеется, он поддерживает весьма ограниченный синтаксис SQL, что не позволяет делать "живыми" запросы, использующие расширенные конструкции SQL, пользовательские функции или специфические для конкретного сервера особенности. Например, для организации "живого" запроса вместо

SELECT * FROM TABLE
WHERE FIELD STARTING WITH 'A'

придется писать

SELECT * FROM TABLE
WHERE FIELD LIKE 'A%'

Подобную замену еще можно пережить, но не всегда возможно найти замену конструкции, которую не понимает Local SQL, и прекрасно понимает сервер.

примечание: вы сами можете убедиться в изложенном, поместив первый запрос в TQuery, переключив RequestLive в True. Попытайтесь установить Active компонента в True и посмотрите что получится.

Собственно, как вы поняли, на самом деле никаких "живых" запросов не существует. В SQL оператор SELECT выполняет только чтение, а вставить, обновить или удалить записи можно только операторами INSERT, UPDATE и DELETE, и никак иначе.

При переключении TQuery.RequestLive:=True TQuery начинает вести себя как TTable - т.е. он сначала разбирает запрос, извлекает оттуда имя таблицы, и потом выбирает информацию из системных таблиц о полях таблицы, индексах и т.п. Вы можете все это увидеть в SQL Monitor.

FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

Сообщение FilSCool » 25 сен 2007, 13:47

kdv писал(а): меня уже смех разбирает, если честно.
что ж ты, злыдень, не можешь прочитать
Мля, не поверишь... бывает же.. - сегодня на свежую голову дошло, "как это работает". И сам ржаль.

Как понял IBDataSet при "редактировании" базы(вставка, например) методом компонентных функций:

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

IBDataSet1->Insert(); 
IBDataSet1->FieldByName("Field1")->AsString= "aaaaaaa"; 
IBDataSet1->Post();
тупо вызывает прописаный в InsertSQL запрос:
insert into mybase (Field1) values (:Field1)
подставив вместо параметра :Field1 значение "aaaaaaa".
что, впрочем мона делать и самому вручную.

Создал проектик, проверил - работает. :)

kdv писал(а): При переключении TQuery.RequestLive:=True TQuery начинает вести себя как TTable
Так это работает только в BDE-компонентах. IBQuery такого вообще не имеет.

FilSCool
Сообщения: 6
Зарегистрирован: 23 сен 2007, 16:51

Сообщение FilSCool » 26 сен 2007, 16:01

Вот возник попутно вопрос еще...
Много читал про положительность использования отдельных транзакций операциями...

Можно ли используя один IBDataSet, выполнять запросы SelectSQL, InsertSQL, RefreshSQL,... разными транзакциями, а не одной, что прописана по умолчанию, не закрывая DataSet?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 26 сен 2007, 17:16

FilSCool писал(а):Вот возник попутно вопрос еще...
Много читал про положительность использования отдельных транзакций операциями...

Можно ли используя один IBDataSet, выполнять запросы SelectSQL, InsertSQL, RefreshSQL,... разными транзакциями, а не одной, что прописана по умолчанию, не закрывая DataSet?
А ты быстро прогрессируешь и в нужную сторону, молодец :) Не, низзя. Если только залезть к нему в кишки и поправить кое-что в нескольких местах. Квалифицированному человеку работы недели на две-три. Или купить FIBPlus ;)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 26 сен 2007, 18:07

Merlin писал(а):Если только залезть к нему в кишки и поправить кое-что в нескольких местах.
Были ж где-то поправки для IBX, кажись, от Фаниса?
Только не помню, где :(

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 26 сен 2007, 18:24

WildSery писал(а):Были ж где-то поправки для IBX, кажись, от Фаниса?
Только не помню, где :(
Для связки IBQuery-IBUpdateSQL. Где-где, на сайте, вестимо :)

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 26 сен 2007, 18:41

Merlin писал(а):Для связки IBQuery-IBUpdateSQL. Где-где, на сайте, вестимо :)
Ты про вот эту нерабочую ссылку?

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 26 сен 2007, 19:25

WildSery писал(а):
Merlin писал(а):Для связки IBQuery-IBUpdateSQL. Где-где, на сайте, вестимо :)
Ты про вот эту нерабочую ссылку?
Не, я про эту рабочую

http://www.ibase.ru/fibc/wr_trans.txt

работу я не тестил, сам понимаешь.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 26 сен 2007, 19:30

Merlin писал(а):Не, я про эту рабочую
Я про неё помнил смутно, но вот так сходу не смог найти, как туда попасть :oops:

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 26 сен 2007, 19:57

WildSery писал(а):
Merlin писал(а):Не, я про эту рабочую
Я про неё помнил смутно, но вот так сходу не смог найти, как туда попасть :oops:
Я вообще-то тоже :) Просто сам вставлял её когда-то в одну статейку, через неё и вышел ;) Но поиском по 'IBUpdateSQL' тоже должно находиться.

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

Сообщение kdv » 26 сен 2007, 20:58

Слушай, FISCool, мне ведь смеяться надоест, и я осерчаю.
сколько раз можно повторять чтобы ты читал ibx.htm по человечески?

опять цитирую:

IBUpdateSQLW

В поставке такого компонента нет. Зато он есть здесь. Он предназначен для выполнения операторов Select/refresh и insert/update/delete в разных транзакциях. Зачем это нужно, см. дальше информацию по транзакциям в приложении.
...

Эта проблема решается, причем один из способов описан выше - это вынос запросов insert/update/delete в отдельные компоненты IBSQL/IBQuery. Второй способ - использование IBQuery + специальная модификация IBUpdateSQL (см. IBUpdateSQLW выше)


p.s. это просто кандец какой-то... :shock:

Ответить