Форум программистов, компьютерный форум, киберфорум
C++ Builder: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/13: Рейтинг темы: голосов - 13, средняя оценка - 5.00
2 / 2 / 0
Регистрация: 25.05.2009
Сообщений: 105

Ключевое поле для нескольких таблиц

25.05.2009, 10:21. Показов 2564. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго всем времени суток!

Разрабатываю приложение с базой данных в C++builder и столкнулся со следующей проблемой:
Есть 3 таблицы, которые должны быть связаны по ключевому автоинкрементному полю ID. В главной таблице этот ключ задается с помощью генератора. А вот в остальные таблицы этот ключ почему-то не заносится.
Для работы с БД использую Interbase, соответственно набор компонентов в Builder'e InterBase. На форме лежат IBDatabase, IBTransaction и по 3 IBQuery, IBDataSet и DataSource. Автоматически сгенерированный запрос InsertSQL в IBDataSet для зависимой таблицы такой:
insert into HOSPITAL
(ADDRESS, ID, OTDELENIE, PALATA)
values
(:ADDRESS, :ID, :OTDELENIE, :PALATA)

Подскажите пожалуйста как и в какой последовательности следует соединить компоненты, если дело в этом. Или как изменить SQL-запрос на добавление, если дело в этом. Ну или что еще сделать, чтобы все это хозяйство заработало

Заранее спасибо!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.05.2009, 10:21
Ответы с готовыми решениями:

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

Вычисляемое поле из нескольких таблиц
Добрый день! На практике дали курсовую работу: сделать базу данных. Сделал практически всё необходимое, прошу помощи лишь в одном: как...

Ссылка на поле t2.paymentTotal может относиться к полям нескольких таблиц
Я не нашел где это. Но запрос состоит из 3х частей. В вб это выглядет так. s1 = "" s1 = s1 & " SELECT t1.studentCode, " ...

10
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
25.05.2009, 10:31
я в зависимые таблицы записи руками заношу в триггерe на событие Insert
0
2 / 2 / 0
Регистрация: 25.05.2009
Сообщений: 105
25.05.2009, 10:53  [ТС]
VoodooMan
Извини за назойливость, а можешь примерно написать текст триггера? Я новичок в этом деле, никогда с ними не сталкивался.

Огромное спасибо!
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
25.05.2009, 11:17
Лучший ответ Сообщение было отмечено как решение

Решение

Karull, у меня есть под оракл, может выручат:
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
CREATE OR REPLACE TRIGGER DBO.INSERT_ROW
AFTER INSERT
ON DBO.PARAM_QUERY 
REFERENCING NEW AS NEW OLD AS OLD
DECLARE
TYPE curtp IS REF CURSOR;
rd PARAM_QUERY.rid%TYPE;
n_ord PARAM_QUERY.N_ORDER%TYPE;
cur curtp;
BEGIN
OPEN cur FOR
SELECT ROWID
FROM PARAM_QUERY
WHERE rid IS NULL;
FETCH cur INTO rd;
CLOSE cur;
OPEN cur FOR
SELECT LPAD (NVL (MAX (n_order), 0) + 1, 9, '0') maxv FROM PARAM_QUERY;
FETCH cur INTO n_ord;
CLOSE cur;
IF (rd IS NOT NULL)
THEN
UPDATE PARAM_QUERY
SET rid = rd, n_order = n_ord
WHERE rid IS NULL;
INSERT INTO LIN_DATA ld (ld.rid, ld.lin_data, ld.primld)
VALUES (rd, EMPTY_BLOB (), EMPTY_BLOB ());
INSERT INTO PARAM_IZM (rid)
VALUES (rd);
INSERT INTO statistics (rid)
VALUES (rd);
INSERT INTO SMB_ACT (rid)
VALUES (rd);
INSERT INTO abonent (rid)
VALUES (rd);
END IF;
END;
[FONT=Courier][SIZE=2][/SIZE][/FONT]

а вообще вы это можете делать и без триггеров, просто сформировать и вызвать два запроса на insert
0
2 / 2 / 0
Регистрация: 25.05.2009
Сообщений: 105
25.05.2009, 23:31  [ТС]
Ну вот я создал три простеньких триггера, по одному на каждую таблицу:
SQL
1
2
3
4
5
6
7
CREATE TRIGGER TRIGID_GENERAL FOR GENERAL 
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF(NEW.ID IS NULL)THEN
NEW.ID=GEN_ID(GENID,1);
END
Соответственно, создал генератор GENID, который просто прибавляет значение на 1.
Поле GeneratorField элемента IBDataSet не стал заполнять, поскольку полагаю, что триггер будет заполнять его автоматически. Запрос InsertSQL для главной таблицы выглядит так:
SQL
1
2
3
4
INSERT INTO GENERAL
  (BIRTHDAY, HOSPITAL, ID, NAME, SOSTOYANIE)
VALUES
  (:BIRTHDAY, :HOSPITAL, :ID, :NAME, :SOSTOYANIE)
Запросы для остальных 2-х табличек выглядят также, только названия полей различаются. Но при вызове метода Insert() выскакивает ошибка "Field ID must have a value". Что я не так делаю?
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
26.05.2009, 00:11
так по идее тебе надо либо NULL передавать, либо вообще id в запросе не использовать
0
2 / 2 / 0
Регистрация: 25.05.2009
Сообщений: 105
26.05.2009, 19:29  [ТС]
Исключение из InsertSQL поля ID не помогло. Теперь запрос выглядит так:
SQL
1
2
3
4
INSERT INTO GENERAL
  (BIRTHDAY, HOSPITAL, NAME, SOSTOYANIE)
VALUES
  (:BIRTHDAY, :HOSPITAL, :NAME, :SOSTOYANIE)
И все равно при Insert() вылетает эта ошибка. В поле GeneratorField следует устанавливать генератор или все должен делать триггер?
Может быть дело в обработчике нажатия кнопки. Код такой:
C++
1
2
3
4
5
6
DataModule2->IBDataSet1->Insert();
DataModule2->IBDataSet1->FieldByName("Name")->AsString = Form3->Edit1->Text + " " + Form3->Edit2->Text + " " + Form3->Edit3->Text;
DataModule2->IBDataSet1->FieldByName("Birthday")->AsString = Form3->Edit4->Text;
DataModule2->IBDataSet1->FieldByName("Sostoyanie")->AsString = Form3->Edit6->Text;
DataModule2->IBDataSet1->FieldByName("Hospital")->AsString = Form3->Edit8->Text;
DataModule2->IBDataSet1->Post();
Может быть есть еще какие-то мысли?
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
26.05.2009, 19:40
Karull, я вот так генерю новое значение:
C++
1
SELECT LPAD (NVL (MAX (n_order), 0) + 1, 9, '0') maxv FROM PARAM_QUERY;
просто опыта работы с интербейсом нет... а еще ты бы новое значение генерил до Insert, а не после...
0
2 / 2 / 0
Регистрация: 25.05.2009
Сообщений: 105
26.05.2009, 23:29  [ТС]
Это, насколько я понимаю, SQL-код
А насчет генерации нового значения, вы имеете в виду, что строка с Insert() должна быть куда-то перемещена?
Генератор GENID генерит новое значение по событию "On New Record". То есть по вызову как раз функции Insert(), я полагаю.
SQL
1
SELECT LPAD (NVL (MAX (n_order), 0) + 1, 9, '0') maxv FROM PARAM_QUERY;
Этим хитрым способом вы находите максимальное существующее значение и прибавляете 1? Это отдельный SQL-запрос, генерирующий значение ключа?

Еще раз дико извиняюсь за назойливость, но уж больно хочется научиться
0
Почетный модератор
 Аватар для Lord_Voodoo
8785 / 2538 / 144
Регистрация: 07.03.2007
Сообщений: 11,873
26.05.2009, 23:41
ну судя по вашему триггеру, вы после добавления записи пытаетесь генерить ей код, поэтому и не нравится базе такое, тем более если ключ указан как обязательно непустой
да ничего хитрого в моем запросе. просто беру максимальный в данный момент и прибавляю 1, вот тебе новый код. проверено, работает в многопользовательском режиме...
0
Комбайнёр
 Аватар для MAcK
1606 / 704 / 77
Регистрация: 27.05.2008
Сообщений: 2,535
27.05.2009, 08:30
Можно использовать ГУИД (GUID) вместо идентификатора ...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.05.2009, 08:30
Помогаю со студенческими работами здесь

Как вывести данные из нескольких таблиц, если в запросе есть поле с NULL?
select Таблица1_ПолеА, Таблица1_ПолеБ, Таблица2_ПолеВ from Таблица1, Таблица2 where Таблица1.ID_ПолеВ=Таблица2.ID_ПолеВЕсли...

Объединение нескольких таблиц, содержащих поле с типом данных "Вложение"
Добрый день! Есть две базы данных: контракты за 2013 и контракты за 2014, в которых существуют таблицы с контрактами, содержащие поле с...

ключевое поле
Не знаю сложный это вопрос или нет, я с SQL SERVER раньше не работал. Задача следующая: Есть ключевое поле, связанное с другим полем в...

Ключевое поле
В форму в три поля вводится ФИО заявителя. Ключевое поле состоит из 1-х трех букв ФИО заявителя. Например, Иванов Сергей Петрович,...

Ключевое поле
На кнопке есть следующий код, поле ЖЕТОН является ключевым и значения на нем не могут повторяться. На форме есть "менюшка",...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru