20.03.2019, 19:35 [+3 UTC]
в нашей команде: 3 475 чел. | участники онлайн: 3 (рекорд: 21)

:: РЕГИСТРАЦИЯ

задать вопрос

все разделы

правила

новости

участники

доска почёта

форум

блоги

поиск

статистика

наш журнал

наши встречи

наша галерея

отзывы о нас

поддержка

руководство

Версия системы:
7.72 (17.03.2019)
JS-v.1.33 | CSS-v.3.35

Общие новости:
09.03.2019, 10:08

Форум:
18.03.2019, 16:49

Последний вопрос:
19.03.2019, 15:15
Всего: 149055

Последний ответ:
20.03.2019, 15:13
Всего: 258006

Последняя рассылка:
20.03.2019, 17:45

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
26.04.2010, 14:34 »
Dimon4ik
Спасибо большое. Все ссылки замечательны. Очень полезная информация. [вопрос № 178042, ответ № 261037]
25.07.2011, 08:19 »
Сергей К.
Спасибо за развернутый ответ! Просветили во многих вопросах. [вопрос № 183801, ответ № 267950]

РАЗДЕЛ • Pascal / Delphi / Lazarus

Создание программ на языках Pascal, Delphi и Lazarus.

[администратор рассылки: Зенченко Константин Николаевич (Старший модератор)]

Лучшие эксперты в этом разделе

Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 473
zdwork
Статус: 1-й класс
Рейтинг: 126
puporev
Статус: Профессионал
Рейтинг: 104

Перейти к консультации №:
 

Консультация онлайн # 142456
Раздел: • Pascal / Delphi / Lazarus
Автор вопроса: Минеев Андрей Анатольевич
Отправлена: 28.08.2008, 07:50
Поступило ответов: 0

Здравствуйте, уважаемые эксперты.

Delphi
FireBird 2

Есть таблица, первое поле которой: ID - autoincrement (триггер и генератор), подключаюсь к базе через dbExpress (TSimpleDataSet).

Пытаюсь добавить новую запись:

SimpleDataSet.Insert;
SimpleDataSet.FieldByName('str_field').AsString := 'Test';
SimpleDataSet.FieldByName('int_field').AsInteger := 1;
SimpleDataSet.Post;

Однако при попытке внести изменения (Post) выскакивает ошибка "Field 'ID' must have a value", но ведь сервер должен назначать новое значение автоинкремент-поля сам.

Что я не так делаю? Подскажите!!!

Состояние: Консультация закрыта

Oтветов пока не поступило.

Мини-форум консультации № 142456

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 1

= общий = | 28.08.2008, 08:36 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Минеев Андрей Анатольевич
... но ведь сервер должен назначать новое значение автоинкремент-поля сам.

Он это будет делать только при соблюдении двух условий:
1. Вы не забыли задать генератор.
2. Текст триггера вставляет сгенерированное значение в нужное поле.
По первому условию можно поверить Вам на слово, а вот по второму условию извините... smile
Текст триггера приведите пожалуйста.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 2

= общий = | 28.08.2008, 09:21

AS
begin
if ((NEW.ID IS NULL) OR (NEW.ID = 0)) then
NEW.ID = gen_id(T_GEN_ID, 1);

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 3

= общий = | 28.08.2008, 09:53 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Минеев Андрей Анатольевич

Нет, текст триггера полностью . Например:
CREATE TRIGGER ИмяТриггера FOR ИмяТаблицы
BEFORE или AFTER
DELETE или INSERT или UPDATE
AS
BEGIN
ТелоТриггера
END

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 4

= общий = | 28.08.2008, 10:01

Триггер я создавал при помощи IBExpert (плохо знаю SQL), а уже в созданный триггер вставил код
В его настройках выставил срабатывание BEFORE при INSERT

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 5

= общий = | 28.08.2008, 10:28 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Минеев Андрей Анатольевич
Хм... Ну что Вам тут сказать...
Работать автоинкремент будет только в одном случае - если Вы написали триггер вида BEFORE INSERT, т.е. триггер, который срабатывает до вставки новой записи.
Советы:
- не задавайте столбцу ID значение DEFAULT.
- не ставьте этому столбцу NOT NULL.
тогда проверку можно укоротить и, следовательно, ускорить:
IF NEW.id IS NULL
...

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 6

= общий = | 28.08.2008, 10:33

Тут нашел статью http://www.ibase.ru/devinfo/generator.htm, там есть интересный момент

цитата:
Конечно, триггер можно оставить, изменив лишь код

IF (NEW.CLIENT_ID IS NULL) THEN
NEW.CLIENT_ID = GEN_ID(NEWID, 1);
чтобы если никакое значение столбца CLIENT_ID при вставке записи из приложения не передано, то оно было сгенерировано автоматически.

примечание: первая попытка перенести ответственность за автоматическую нумерацию столбца первичного ключа таблицы обычно проваливается из-за компонент доступа. Поскольку такой столбец объявлен как not null, и компоненты автоматически считывают характеристики столбцов, у TField будет установлено в True свойство Required. Это не дает возможности оставить столбец "пустым" при передаче с клиента на сервер. Установите свойство Required у такого столбца в False .
Конец цитаты.

Вот меня интересует может это из этого (выделил жирным), просто сейчас в данный момент не могу попробывать. Как вы думаете?

Да, столбцу ID у меня присвоенно NOT NULL, значит нужно убрать?

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 7

= общий = | 28.08.2008, 10:52 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Это относится не к серверу, а компоненту в Вашей программе.
Работает то что Вы написали так:
- если стоит Required:=True, т.е. значение в поле должно быть обязательно, то проверку обязательности проводит сначала сам компонент. Если значения нет, то данные на сервер для вставки вообще не отправляются. По этой причине нельзя смешивать политику проверки данных компонента с сервером. Лучше сделать это только на сервере, тогда Вы можете обращаться к базе из люой программы, а не только из той, что написали Вы и при этом будете уверены, что данные вставляются корректно.
Это утверждение верно, но, по-моему, должно появляться сообщение Дельфи, что столбец не должен оставаться пустым, а у Вас ведь этого нет.
Проверьте, правильно ли Вы написали триггер таким способом:
- зайдите в каталог, где у Вас установлен FireBird. Там в подкаталоге BIN есть программа isql.exe. Это командный интерпретатор SQL комманд.
- зайдя, выберите свою базу данных (SELECT DATABASE ИмяВашейБазыДанных;) и попытайтесь вставить новую строку в Вашу таблицу:
INSERT INTO ИмяТаблицы (tr_field) VALUES ('Test');
- теперь посмотрите что получилось:
SELECT * FROM ИмяТаблицы;
Если автоинкремент работает, то в выводе результатов запроса, рядом со словом 'Test' будет стоять тот номер, который вставил триггер. Если триггер написан неправильно, то номера никакого не будет или выскочит сообщение об ошибке при вставке.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 8

= общий = | 28.08.2008, 10:54

Спасибо, вечером попробую и отпишусь.

p.s. Да вспомнил, я через IBExpert пробывал вставлять новую запись, все работало нормально, запись добавлялась и поле ID увеличивалось, значит триггер срабатывает правильно, возможно это все таки на уровне компонента TSimpleDataSet.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 9

= общий = | 28.08.2008, 10:57 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Минеев Андрей Анатольевич
Да, столбцу ID у меня присвоенно NOT NULL, значит нужно убрать?

Ну, в принципе, можно и не убирать, т.к. значение генератора у Вас должно присваиваться до вставки записи. Но, согласитесь, если значения NULL всё равно там не будет, то излишне напрягать сервер, который должен проверять значение на NOT NULL. Другое дело, если Вы зачем-то будете редактировать уже готовый столбец ID (а делать этого не нужно, т.к. нарушиться связность данных между таблицами), тогда NOT NULL там нужен.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 10

= общий = | 28.08.2008, 11:05

Да и еще, я как понял DbExpress работает с данными локально, пока не поступит команда ApplyUpdate, значит при выполнении команды Post ни чего никуда не отправляется и поэтому наверно ошибку выдает TSimpleDataSet.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 11

= общий = | 28.08.2008, 11:47 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Минеев Андрей Анатольевич
...я как понял DbExpress работает с данными локально, пока не поступит команда ApplyUpdate, значит при выполнении команды Post ни чего никуда не отправляется и поэтому наверно ошибку выдает TSimpleDataSet.

Совершенно верно. TSimpleDataSet работает с локальным набором данных, полученным с сервера.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 12

= общий = | 28.08.2008, 15:53

© Цитата:
Спасибо, вечером попробую и отпишусь

Вот, что у меня получилось:
Через isql.exe у меня не получилось, поэтому пробывал через IBExpert.
Как я уже писал при добавлении через IBExpert все нормально добавляется, счетчик увеличивается.
Свойство Required поля "ID" (SimpleDataSet) поставил False - выскочила ошибка (Project Proba.exe raised exception class EDBClient with message 'Field value reguired.'),
затем в таблице убрал с поля "ID" NOT NULL, оставив cвойство Required поля "ID" (SimpleDataSet) - False, все заработало, записи стали нормально добавляться.
Что вы можете сказать по этому поводу? Можно так оставить или нет?

И еще вопрос, может в триггере оставить только строку NEW.CLIENT_ID = GEN_ID(NEWID, 1) вообще без проверок, опасно это иле нет (редактировать "ID" я не буду?

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 13

= общий = | 28.08.2008, 18:30 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата:
Что вы можете сказать по этому поводу? Можно так оставить или нет?

Вот как раз так и надо. smile
Смотрите, что получается. Если Required:=True, то наличие значения в поле ID проверяется Вашей программой ещё до того , как запись уйдёт на сервер для вставки в таблицу и если значения в поле ID нет, то именно ваша программа (а не сервер) выдаёт сообщение об ошибке.
Если Required:=False, а в свойтве поля ID на сервере стоит NOT NULL, то ошибку уже выдаст вам сервер, т.к. сервер тоже проверяет до вставки записи значение поля на NOT NULL.
© Цитата:
...может в триггере оставить только строку NEW.CLIENT_ID = GEN_ID(NEWID, 1) вообще без проверок, опасно это иле нет...

Лучше не надо. Вполне возможно, что Вам понадобится в будущем изменить последовательность номеров в поле ID и Вы введёт значение поля вручную. Тогда проверка позволит избежать перекрытия вручную введённого значения генератором.
Впрочем, если ручного ввода значения не будет, то можно обойтись и без проверки. Т.е. вводить или не вводить проверку зависит от логики работы с данными. Самому серверу это абсолютно по барабану.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

неизвестный

# 14

= общий = | 28.08.2008, 18:35

Спасибо Вам огромное!!!
Вы очень мне помогли. smile

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Мастер-Эксперт

ID: 425

# 15

= общий = | 28.08.2008, 18:39 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Пожалуйста! smile
Заходите, если что... smile

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

 

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

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.15059 сек.

© 2001-2019, Портал RFPRO.RU, Россия
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.72 от 17.03.2019
Версия JS: 1.33 | Версия CSS: 3.35