![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Один к одному [IB6.x, FB]
Гоблин © (2006-11-15 21:22:00)Привет
Собственно, как реализовать сабж? Про один ко многим всё понятно, а про сабж никак не могу найти.
Гоблин (2006-11-30 20:16:00) [1]Ну ладно, ещё раз спасибо.
Всех целую.
atruhin (2006-11-26 00:52:00) [2]> Вы уверены в этом ?
Ну с поправкой, что мы говорим о FB, то уверен.
MsGuns (2006-11-25 23:15:00) [3]>atruhin © (25.11.06 20:18) [30]
>но в любом случае, управлять транзакциями в процедурах нельзя.
Вы уверены в этом ?
Гоблин (2006-11-25 21:19:00) [4]А, т.е. процедуру запускать в контексте транзакции с клиента?
С ibase.ru выкачал всё, что можно, и что нельзя.
Для FB 2.0 проще, наверное, будет так
CREATE PROCEDURE SETNAMES (parent_ID INTEGER, Name_ Varchar(20), Table SMALLINT)
RETURNS (DID INTEGER)
AS
BEGIN
INSERT INTO CATALOG (Name, Object_type) VALUES (:Name_, :Table) RETURNING ID INTO :DID;
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:DID, :parent_ID);
END
А инкремент ID через триггер.
atruhin (2006-11-25 20:20:00) [5]А еще лучше сходить на www.ibase.ru
Там прочитать ВСЕ статьи, в них найдешь ответы на все твои вопросы.
atruhin (2006-11-25 20:18:00) [6]> А вот такая хранимка будет работать или нет
SET TRANSACTION;,COMMIT;- лишнии, вроде даже не скомпилируется, но
в любом случае, управлять транзакциями в процедурах нельзя.
Вообще должно быть примерно так:
CID = gen_id(GEN_CATALOG_ID, 1);
INSERT INTO CATALOG (ID, Name, Object_type) VALUES (:CID, :NAME_, :Table);
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:CID, :parent_ID);
Гоблин (2006-11-25 19:17:00) [7]А вот такая хранимка будет работать или нет
CREATE TABLE CATALOG
(
ID INTEGER NOT NULL,
Name VARCHAR(50) CHARACTER SET WIN1251 NOT NULL,
Object_type SMALLINT NOT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE TREE
(
ID INTEGER NOT NULL,
Sys_ID INTEGER NOT NULL,
SysParent_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT RTREE FOREIGN KEY (Sys_ID) REFERENCES CATALOG (ID),
CONSTRAINT RTREEPARENTSYS FOREIGN KEY (SysParent_ID) CATALOG (ID)
);
CREATE PROCEDURE SETNAMES (parent_ID INTEGER, Name_ Varchar(20), Table SMALLINT)
RETURNS (DID INTEGER)
AS
BEGIN
SET TRANSACTION;
INSERT INTO CATALOG (Name, Object_type) VALUES ('(dummy)', :Table);
SELECT C.ID FROM CATALOG C WHERE C.Name = '(dummy)' INTO :DID;
INSERT INTO TREE (Sys_ID, SysParent_ID) VALUES (:DID, :parent_ID);
UPDATE CATALOG SET Name = :Name_ WHERE ID = :DID;
COMMIT;
END
Гоблин (2006-11-24 17:44:00) [8]А как бы тогда значение ID на клиента переслать?
atruhin (2006-11-24 06:22:00) [9]Да, они
Гоблин (2006-11-23 20:03:00) [10]
> В триггере и так доступны все поля строки той таблицы, на
> которую он сработал. Читай LangRef.pdf
Это случаем не OLD и NEW?
Desdechado (2006-11-22 21:17:00) [11]У тебя каша в голове.
Справочник, этота таблица, НА которую ссылаются. Она же MASTER-таблица или главная.
Поэтому при удалении из главной в зависимости от того, как ты опишешь внешний ключ в подчиненной таблице,так и будет себя вести. Если с ON DELETE CASCADE, то удалятся записи и в подчиненной тоже. Если без CASCADE, то будет ошибка - надо сначала удалять записи из подчиненной, потом из главной.
Если же боишься удаления из подчиненной напрямую, напиши процедуру удаления, которая будет удалять сразу из двух таблиц. И дай процедуре право на удаление из этих таблиц. А у юзера отними права на удаление из этих таблиц напрямую.
> как узнать ID текущей записи в главной таблице и передать в триггер
В триггере и так доступны все поля строки той таблицы, на которую он сработал. Читай LangRef.pdf
Гоблин (2006-11-22 21:06:00) [12]Т.е. этот триггер должен вставить не важно что в подчинённую таблицу - лишь бы вставил. Но как узнать ID текущей записи в главной таблице и передать в триггер? Можно ли для этого использовать значение генератора?
А как же быть с удалением? Я ж могу что-то удалить из справочника, а главная об этом ничего знать не будет.
MsGuns (2006-11-22 20:39:00) [13]>Гоблин (22.11.06 19:25) [21]
>Последний вопрос. Вставку записей сразу в две таблицы с FK между ними нельзя сразу сделать?
Можно. Для этого и существуют транзакции
>Либо два запроса, либо через ХП. Я не прав?
Для сервера в сущности все едино: выполняются ли две вставки в таблицы (или таблицу) двумя клиентскими запросами или в контексте одного скрипта (хранимки) двумя шагами, оформленными каждый как запрос.
Главное - все существующие стандарты сиквеля не позволяют в одном SQL-операторевносить изменения более чем в одну таблицу (И ЭТО ПРАВИЛЬНО !!!)
Desdechado (2006-11-22 20:30:00) [14]> Последний вопрос.
Операции строго последовательные, хоть сами по себе, хоть в ХП.
> пример такого триггера
например, в after insert-триггере на главную таблицу делать insert в подчиненную сразу
Гоблин (2006-11-22 19:25:00) [15]Ай, извиняюсь. Въехал.
Последний вопрос. Вставку записей сразу в две таблицы с FK между ними нельзя сразу сделать? Либо два запроса, либо через ХП. Я не прав?
> Desdechado © (18.11.06 20:19) [15]
> Это уже задача триггера.
А можно пример такого триггера? А то моя идея проверять все поля на предмет вставки мне что-то не нравится.
Desdechado (2006-11-22 12:22:00) [16]> А вот в случае IB\FB в таких таблицах можно использовать один генератор на все таблицы или по отдельности?
Без разницы. Но я предпочитаю каждой таблице по генератору (если в ней есть, чего нумеровать).
atruhin (2006-11-22 12:14:00) [17]> Или в системной таблице вообще на пологаться на автоинкремент,
> а брать ID из справочников?
ничего не понятно
Гоблин (2006-11-21 22:09:00) [18]А вот в случае IB\FB в таких таблицах можно использовать один генератор на все таблицы или по отдельности? Или в системной таблице вообще на пологаться на автоинкремент, а брать ID из справочников?
atruhin (2006-11-18 20:59:00) [19]> В случае одной таблицы not null там, где это надо.
Создаешь модифицируемое представление, на него права и ограничения,
на таблицы прав не даешь.
Гоблин (2006-11-18 20:48:00) [20]В случае одной таблицы not null там, где это надо.