Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > id несуществующей записи


Автор: opx 28.5.2009, 12:52
Я наверное что-то не понимаю, но все же
Есть 2 таблицы: 
Код

CREATE TABLE FIRMS (
  ID INTEGER NOT NULL,
  NAME VARCHAR(255),
  ID_CITY INTEGER);
ALTER TABLE FIRMS ADD PRIMARY KEY (ID);
ALTER TABLE FIRMS ADD CONSTRAINT FK_FIRMS FOREIGN KEY (ID_CITY) REFERENCES CITY(ID) ON DELETE SET NULL;

SET TERM ^ ;

CREATE TRIGGER BI_FIRMS_ID FOR FIRMS
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
      NEW.ID = GEN_ID(FIRMS_ID_GEN, 1);
END^

SET TERM ; ^

и
Код

CREATE TABLE CITY (
  ID INTEGER NOT NULL,
  NAME VARCHAR(100));
ALTER TABLE CITY ADD PRIMARY KEY (ID);

SET TERM ^ ;

CREATE TRIGGER BI_CITY_ID FOR CITY
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
      NEW.ID = GEN_ID(CITY_ID_GEN, 1);
END^

SET TERM ; ^

Т. е. записи добавляются, id генерируются. Одно непонятно.
Есть у меня информация о фирме: ООО "Форум", г. Н. Новгород
г. Н. Новгород отсутствует в таблице CITY
Если я вставлю запись в CITY то мне нужно ее ID передать в Firms да так, чтобы другой юзер в это время добавлял бы записи и получал свои ID. Как бы это сделать?
Если после метода Post вытаскивать запросом:
Код

SELECT GEN_ ID (NEWID, 1) FROM RDB$DATABASE

То я могу напороться на ID другого пользователя. Поправьте, если я ошибаюсь

Автор: Gluttton 28.5.2009, 14:02
Код

INSERT INTO FIRMS(NAME, ID_CITY)
SELECT "ООО Форум", CITY.ID
FROM CITY
    WHERE CITY.NAME="Н.Новгород"


Так?

При этом рекомендую наложить на CITY.NAME ограничение UNIQUE, что б два Н.Новгорода не появилось smile !

Не давно (за последние две недели) на ветке форума "Базы данных" была тема про правильность написаня названий районов и городов, БД там какая то про гостиницы была... Так вот там было озвучено очень интересное (на мой взгляд) предложение реализации того, что бы корректно обробатывать ситуации, когда разные пользователи по разному называют города (например. Н.Новгород, Нов. Новгород, Новый Новгород), а БД при этом корректно относит их к одному (эталонному названию: Новый Новгород).

Автор: opx 28.5.2009, 14:55
Так то оно так... но 
Цитата
 Одно непонятно.
Есть у меня информация о фирме: ООО "Форум", г. Н. Новгород 
г. Н. Новгород отсутствует в таблице CITY


Добавлено через 4 минуты и 20 секунд
Нет. Этого города еще нет в списке. Нужно добавить город и Фирму с ID этого города и чтобы не пересечься с другим пользователем

Автор: Gluttton 28.5.2009, 15:26
Цитата

Нет. Этого города еще нет в списке. Нужно добавить город и Фирму с ID этого города и чтобы не пересечься с другим пользователем

И непременно одним запросом?

1. Выполняем запрос:
Код

SELECT *
FROM CITY
    WHERE CITY.NAME="Н.Новгород"


2. Если запрос возвращает NULL, то:
Код

INSERT INTO CITY(NAME) VALUES("Н.Новгород")


3. Не зависимо от результата п.п. 1, 2:
Код

INSERT INTO FIRMS(NAME, ID_CITY)
SELECT "ООО Форум", CITY.ID
FROM CITY
    WHERE CITY.NAME="Н.Новгород"


А как за один запрос выполнить это всё я не знаю. Возможно в этом может помочь EXCEPTION + TRIGGER + PROCEDURE.

Автор: Deniz 28.5.2009, 15:39
Код
id_City = Gen_ID(NEWID, 1);
insert into City (id, name) values(id_City, "Н.Новгород")
insert into firms(name, ID_City) values ("ООО Форум", id_City);

Если есть уникальный индекс в City по Name, то метод Gluttton, тоже подойдет, он просто забыл дописать вставку в City.

Автор: opx 28.5.2009, 15:53
Так и думал, что я туплю. Спасибо, что подсказали

Автор: Bose 7.6.2009, 06:17
Цитата(opx @  28.5.2009,  11:52 Найти цитируемый пост)
Если после метода Post вытаскивать запросом:

SELECT GEN_ ID (NEWID, 1) FROM RDB$DATABASE

То я могу напороться на ID другого пользователя. Поправьте, если я ошибаюсь

Не напорешься, при условии что NEWID гарантированно больше самого большого ID в таблице. GEN_ID выполняется вне транзакций.

Автор: Deniz 8.6.2009, 05:21
Цитата(Bose @  7.6.2009,  09:17 Найти цитируемый пост)
Не напорешься, при условии что NEWID гарантированно больше самого большого ID в таблице.
он просто получит новый уникальный ID, которого еще нигде нет.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)