Delphi+Firebird: помогите правильно написать команду!

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

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

POROX
Сообщения: 3
Зарегистрирован: 01 авг 2005, 16:53

Delphi+Firebird: помогите правильно написать команду!

Сообщение POROX » 01 авг 2005, 17:01

Как известно при работе с СУБД Firebird существует геморрой описание строковых констант в командах SQL - хавает одинарные:
Как правильно написать команду на удаление записи в таблице
у меня получается ошибка:

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

Form1.IBQuery1.SQL.Add('delete from table1 where nomer=Form1.IBQuery1.FieldByName('Nomer').Value');
как правильно указать строку 'Nomer'?

tie
Сообщения: 39
Зарегистрирован: 14 июл 2005, 12:12

Сообщение tie » 03 авг 2005, 15:27

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

Form1.IBQuery1.SQL.Add('delete from table1 where nomer='''+Form1.IBQuery1.FieldByName('Nomer').AsString+''''); 
а ради хохмы попробуй вот так:

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

Form1.IBQuery1.SQL.Add('delete from table1 where nomer='''+Form1.IBQuery1('Nomer')+'''');

D_Stranger
Сообщения: 6
Зарегистрирован: 14 фев 2007, 11:30

Сообщение D_Stranger » 15 фев 2007, 09:48

в общем с недавних пор я перехожу с BDE на FireBird. С кодом проблем пока не возникало, т.к. почитываю мануалы с сайта. Но пока не могу допетрить до парочки моментов. Када запущена транзакция, то выполненный запрос уже храница на клиенте? и еще, как при помощи DBGrida можно изменять данные (любые цифры к определенной колонке).
после чего как я понял, если пользователь решил потвердить свои изменения - вызвать commit, если отменить - rollback...
для справки:
пишу на Delphi 7
параметры транзакции:
read_committed
rec_version
nowait

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

Сообщение kdv » 15 фев 2007, 10:12

Када запущена транзакция, то выполненный запрос уже храница на клиенте?
бррр.. запрос отправляется с клиента на сервер. сервер возвращает клиенту результат, как об этом просит клиент. Клиент может выполнить запрос и не брать результат. Может взять результат частично. А может и целиком.

про "грид" лучше прочитать тут: www.ibase.ru/devinfo/ibx.htm#ibdataset

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

Сообщение Dimitry Sibiryakov » 15 фев 2007, 10:13

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

D_Stranger
Сообщения: 6
Зарегистрирован: 14 фев 2007, 11:30

Сообщение D_Stranger » 15 фев 2007, 10:18

kdv писал(а):про "грид" лучше прочитать тут: www.ibase.ru/devinfo/ibx.htm#ibdataset
читал уже. но в этой главе только про Dataset (о "гриде" не слова). да и Dataset использовать не хочу... может ошибаюсь...
Dimitry Sibiryakov писал(а):А в гриде лучше вообще не редактировать
а как лучше?

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

Сообщение Dimitry Sibiryakov » 15 фев 2007, 10:37

D_Stranger писал(а):а как лучше?
В отдельной форме на каждую сущность. Хотя есть и исключения... но тебе лучше о них пока не знать - приходит с опытом.

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

Сообщение kdv » 15 фев 2007, 10:43

читал уже. но в этой главе только про Dataset (о "гриде" не слова). да и Dataset использовать не хочу... может ошибаюсь...
ужас. Грид ПОКАЗЫВАЕТ данные. Датасет их ПОЛУЧАЕТ С СЕРВЕРА, и позволяет "редактировать".
Читать-то может ты и читал, только не понял. Я в свою очередь вот чего не пойму - как ты с BDE работал? Архитектура работы с данными в дельфях начиная с самых первых одна и та же
Database - DataSet - DataSource - DBControls

и - грид сам по себе ничего не редактирует. т.е. он позволяет редактировать, но только некий БУФЕР. Который отправляет в DataSource, а он, в свою очередь, отправляет DataSet-у. А уж DataSet либо может вызвать для отправки на сервер изменений, при помощи insert/delete/update, либо не может, если они не прописаны или это голый IBQuery (тот же датасет).

ты хоть что-нибудь на эту тему читал? просто я не представляю себе, как можно писать программы, бросая компоненты на формы и вообще не понимая, как эти компоненты взаимосвязаны...

D_Stranger
Сообщения: 6
Зарегистрирован: 14 фев 2007, 11:30

Сообщение D_Stranger » 15 фев 2007, 10:45

Dimitry Sibiryakov писал(а):В отдельной форме на каждую сущность.
мой запрос собирает данные с двух сущностей. результат просматривается в "дбгриде", т.к. есесно это удобно.
Необходимо: пользователь должен иметь возможность при помощи грида (или если возможно InputQuery('bla','bla',variable)) изменить значения одного из аттрибутов.
если есть более грамотные механизмы, буду рад.

D_Stranger
Сообщения: 6
Зарегистрирован: 14 фев 2007, 11:30

Сообщение D_Stranger » 15 фев 2007, 10:50

to kdv
как ни странно в BDE всё получалось
но щас стал вопрос о многопользовательском режиме и т.д. т.п.
чтоб сильно не материли: работаю с БД около 3 месяцев (пришлось). возможно еще более года придеца работать с ними...
PPS: планы на дальнейщую работу немного другие, но данную задачу решить всё же надо!

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

Сообщение WildSery » 15 фев 2007, 11:02

D_Stranger писал(а):мой запрос собирает данные с двух сущностей.
Сущность - это не таблица, а некий объект предметной области, в которой собираешься вести учёт. Например "Номенклатура".
Для редактирования строки грида, в которой показана та же номенклатура (как правило, в гриде показана только часть возможных свойств), тыкаем кнопку "редактировать" и открываем модальную форму, где не в виде грида, а в виде отдельных DB-контролов всё красиво расставлено, удобно для просмотра и редактирования. Затем нажимаем "ок" и данные сохраняются, обновля затем строку грида.

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

Сообщение Dimitry Sibiryakov » 15 фев 2007, 11:02

D_Stranger писал(а):мой запрос собирает данные с двух сущностей. результат просматривается в "дбгриде"
У нас с тобой разные понятия "сущностей". Две мои сущности в один грид не свести, ибо у них разное количество и тип аттрибутов. И редактировать их в гриде неудобно, поскольку количество атрибутов велико и не все из них "плоские".

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

Сообщение kdv » 15 фев 2007, 11:52

но щас стал вопрос о многопользовательском режиме и т.д. т.п.
многопользовательский режим тут совершенно ни при чем.
как ни странно в BDE всё получалось
при работе с TTable и TQuery? :) верю. Потому что они автоматически формируют SQL insert/delete/update при "редактировании" данных. И это описано тут:
www.ibase.ru/devinfo/bde.htm
В реале никакого "редактирования" запросов с SQL-серверами нет - select только читает данные, не более того.
Именно поэтому я рекомендовал читать про IBDataSet.
пользователь должен иметь возможность при помощи грида
а если запрос выполняется над тремя, четырьмя или более таблицами - что надо редактировать?
Вот допустим, ты выбираешь запросом ФИО клиента и номер его заказа.

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

select c.name, o.id
from oders o, clients c
where o.cid = c.id
ну и как тут редактировать ИМЯ клиента (c.name), если в выборке отсутствует c.id ? Именно поэтому подобное редактирование в гриде порочно, т.к. организовать-то такое конечно можно - выбрать c.id, "спрятать" его от пользователя, и т.д. А если например, запрос будет еще выбирать дату заказа - o.dt, и пользователь захочет одновременно поменять И имя клиента И дату заказа???
я еще раз подчеркиваю, что да, это можно сделать. Или процедурой, или при помощью view с триггерами. Но лучше так не делать.
То есть не давать редактировать в гриде одновременно справочные и "оперативные" данные, из разных таблиц.

D_Stranger
Сообщения: 6
Зарегистрирован: 14 фев 2007, 11:30

Сообщение D_Stranger » 15 фев 2007, 12:58

to kdv
написано доступно и очевидное.

но, до самого механизма транзакций я пока не допёр. в каких моментах нужно ее стартовать и завершать.
сегодня закончилось всё тем, что пока запросом "update..." так сказать в realtime путем изменения нужных данных в почти "модальном" окне после подтверждения_изменения запись меняется сразу же в БД.
товарищи! подскажите, как добиться того, чтобы пользователь в рекомендованном вами (или нет) модальном_окне мог вносить изменения для каждой_необходимой записи. а потом по нажатию одной из 2-х кнопок (ок/отмена) данные сохранялись/изменялись на сервере и наоборот соотв-но.

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

Сообщение kdv » 15 фев 2007, 13:23

в каких моментах нужно ее стартовать и завершать.
дорогой товарищ! я ЕЩЕ раз дам ссылку -
www.ibase.ru/devinfo/ibx.htm#tran_use
где вполне доступно описано, что такое транзакция и примерно как ими управлять.

Когда я сам изучал транзакции, я прочитал соответствующую главу в документации по InterBase 4 примерно 5 или 6 раз, до тех пор, пока не "дошло".
Так что рекомендую заняться тем же самым, т.е. недонократным прочтением упомянутого документа, до тех пор пока не "дойдет". А потом - читать другие статьи по транзакциям, опять же на ibase.ru :)

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

Сообщение kdv » 15 фев 2007, 13:57

кстати, оказалось что в предыдущих вариантах статьи я наврал по поводу того, что завершение по IBTransaction.Active:=False зависит от DefaultAction. Нифига, в коде явно прописан Rollback, с чем всех, использующих такой метод завершения транзакции, и поздравляю.
статью исправил.

тем не менее, при закрытии IBDatabase открытые транзакции именно так и завершаются - в зависимости от DefaultAction. С чем тоже поздравляю тех, кто допускает в приложении оставленные открытыми транзакции. Потому что в последней версии IBX указано taCommit. А за предыдущие версии и FIBPlus не поручусь - там вполне могло быть taRollback.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 15 фев 2007, 14:47

В FIB+ (6.45) при закрытии базы используется TimeoutAction (в IBX - DefaultAction), которое по дефолту TARollback.
По поводу свойства Active - я так понимаю, что оно существует только из-за того, чтобы можно было запускать и останавливать транзакцию в design-time.

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

    property Active: Boolean read GetInTransaction write SetActive stored DoStoreActive;
Получается, использование в коде свойства Active искажает восприятие транзакции как таковой, позволяя предполагать, что она просто "отключается". Это можно дополнительно отметить в документе...

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

Сообщение kdv » 15 фев 2007, 15:16

В FIB+ (6.45) при закрытии базы используется TimeoutAction (в IBX - DefaultAction), которое по дефолту TARollback.
! Вот я откуда это помню. Спасибо, придется дополнить статью.
оно существует только из-за того, чтобы можно было запускать и останавливать транзакцию в design-time.
ага.
Это можно дополнительно отметить в документе...
я про это написал, во внутреннем линке tran_use сделал доп. абзац.

Не рекомендуется стартовать или завершать транзакции обращением к свойству IBTransaction.Active. В описании IBTransaction об этом уже было сказано, но стоит повторить еще раз - привычка вызывать в коде Active так же, как вы это делаете в дизайн-тайме (кликая на свойство active в Object Inspector) может сослужить плохую службу - при подобном вызове транзакция безусловно завершится по Rollback. Поэтому, а также для улучшения читаемости кода, свойство Active рекомендуется использовать только для проверки состояния компонента (для этого есть свойство inTransaction, кстати). А старт и завершение транзакции всегда писать явно, используя методы StartTransaction, Commit или Rollback.

примечание: в FIBlus DefaultAction равно taRollback. Это нужно учитывать, особенно если вы планируете заменить IBX на FIBPlus. Кстати, если при закрытии IBDatabase к нему "прицеплены" активные транзакции, то они завершаются как раз по DefaultAction, а не как Active:=False. Соответственно, при таком завершении приложения в IBX изменения, произведенные в незакрытых к этому моменту транзакциях сохранятся, а в FIBPlus - исчезнут. Умолчательное поведение обоих наборов компонент может быть нежелательным в различных случаях.

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 15 фев 2007, 15:43

Маленькое уточнение: в FIB+ нет свойства DefaultAction, вместо него - TimeoutAction. При закрытии TpFIBDatabase перебираются все транзакции, вызывая у каждой OnDatabaseDisconnecting. И уже в TFIBTransaction для завершения себя используется TimeoutAction. За одним исключением: если TimeoutAction = TACommitRetaining, вызывается TACommit.
P.S. Не знаю, можно ли мне публиковать кусочки кода библиотеки?

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

Сообщение kdv » 15 фев 2007, 16:12

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

Ответить