Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставка строки с проверкой / 10 сообщений из 10, страница 1 из 1
25.05.2007, 18:30
    #34552517
-=Koba=-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Решил эту задачу на программном уровне а хотелось бы на уровне бд

Есть 2 таблицы
Таблица А (AID, NAME)
Таблица B (BID, COL1, COL2, COL3)

AID и BID sequence колонки

Допустим пользователь запускает следующий скрпит

insert into B (COL1, COL2, COL3) values ("Example111","Example222","Example333")

БД должна проверить если в таблице A в колонке name строка с Example111 и возратить ее AID если нету то соотвественно создать новую запись и возратить ее AID


И в окончательном скрипте изменить Example111 на AID
т.е. получится следующее

insert into B (COL1, COL2, COL3) values (AID, "Example222","Example333")

Подскажите хоть с чего начать.
...
Рейтинг: 0 / 0
25.05.2007, 18:55
    #34552615
ilejn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Я, возможно, торможу (все-таки вечер пятницы), но более красивого решения, чем банальный триггер я здесь не вижу. Начать, соответственно, с изучения триггеров.
...
Рейтинг: 0 / 0
25.05.2007, 23:12
    #34552902
Vladimir Sitnikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
-=Koba=-БД должна проверить если в таблице A в колонке name строка с Example111 и возратить ее AID если нету то соотвественно создать новую запись и возратить ее AID

Подскажите хоть с чего начать.
Начинать нужно с unique constraint 'ов.

Создать этот самый констрейнт, а потом смело добавлять строки в таблицу, и ловить ошибку (либо в хранимой процедуре, либо в приложении) unique_violation

Триггеры здесь не к месту.
...
Рейтинг: 0 / 0
25.05.2007, 23:17
    #34552906
-=Koba=-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Так что здесь будет лучше
Я уже 2 часа над тригерами потею
...
Рейтинг: 0 / 0
26.05.2007, 00:32
    #34552959
Vladimir Sitnikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
-=Koba=-уже 2 часа над тригерами потеюconstraint создали?
...
Рейтинг: 0 / 0
26.05.2007, 02:59
    #34552988
tkopets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Код: plaintext
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.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
-- для цього нам потрібно буде:
CREATE LANGUAGE PLpgSQL;


-- решта --

-- таблиця a
CREATE SEQUENCE seq_a_aid;

CREATE TABLE a
(
   aid integer NOT NULL DEFAULT nextval('seq_a_aid'), 
   name character varying( 20 ) NOT NULL, 
   CONSTRAINT a_aid_pk PRIMARY KEY (aid), 
   CONSTRAINT a_name_uk UNIQUE (name)
);


-- таблиця b
CREATE SEQUENCE seq_b_bid;

CREATE TABLE b
(
  bid integer NOT NULL DEFAULT nextval('seq_b_bid'),
  col1 character varying( 10 ) NOT NULL,  -- на integer хватає 10 знаків
  col2 character varying( 20 ),
  col3 character varying( 20 ),
  CONSTRAINT b_bid_pk PRIMARY KEY (bid)
);


CREATE OR REPLACE FUNCTION trgf_b_trick()
RETURNS TRIGGER AS $BODY$
DECLARE
  vi_aid INTEGER;  -- будем тут тримати наш aid, якщо треба буде вставити
BEGIN
  SELECT aid
    INTO vi_aid
    FROM a
   WHERE a.name = NEW.col1;

  IF NOT FOUND THEN
    INSERT INTO a(name) VALUES (NEW.col1);

    SELECT aid
      INTO vi_aid
      FROM a
     WHERE a.name = NEW.col1;
  END IF;

  NEW.col1 := vi_aid::varchar;  -- то шо витягнули з a (в varchar)

  RETURN NEW;
END;
$BODY$ LANGUAGE PLpgSQL;

CREATE TRIGGER trigger_b_trick BEFORE INSERT
  ON b FOR EACH ROW EXECUTE PROCEDURE trgf_b_trick();

-- тести
insert into a(name) values('test1');
insert into a(name) values('test2');
insert into a(name) values('name_value');
insert into a(name) values('test3');
insert into a(name) values('test4');

insert into b(col1,col2,col3) values('name_value', 'col2value', 'col3value');
insert into b(col1,col2,col3) values('test1', 'col2value', 'col3value');

SELECT * FROM b;
...
Рейтинг: 0 / 0
26.05.2007, 11:41
    #34553113
-=Koba=-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Спасибо. пошел применять
...
Рейтинг: 0 / 0
26.05.2007, 15:19
    #34553235
serejaa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Vladimir Sitnikov -=Koba=-БД должна проверить если в таблице A в колонке name строка с Example111 и возратить ее AID если нету то соотвественно создать новую запись и возратить ее AID

Подскажите хоть с чего начать.
Начинать нужно с unique constraint 'ов.

Создать этот самый констрейнт, а потом смело добавлять строки в таблицу, и ловить ошибку (либо в хранимой процедуре, либо в приложении) unique_violation

Триггеры здесь не к месту.


А что больше будет тормозить ошибка ERROR: duplicate key violates unique constraint "..."

или проверка в триггере , есть ли уже такая запись ?
...
Рейтинг: 0 / 0
26.05.2007, 15:41
    #34553248
Vladimir Sitnikov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Vladimir SitnikovТриггеры здесь не к месту.
Неправильно понял условие. В самом деле, триггер нужен.

serejaaА что больше будет тормозить ошибка ERROR: duplicate key violates unique constraint "..." или проверка в триггере , есть ли уже такая запись ?
Если делать проверку, делать её нужно правильно. Если вы не меняли уровень изоляции транзакций (который по-умолчанию равен read commited), то, может случиться так, что между вашей проверкой и следующим действием кто-то такую строку добавит (== insert может вернуть duplicate key exception даже после проверки "if not found").

Поэтому, в коде триггера trgf_b_trick _нужно_ обрабатывать duplicate key в случае insert'а (в данном случае, можно просто проигнорировать это исключение)
...
Рейтинг: 0 / 0
26.05.2007, 23:27
    #34553491
tkopets
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вставка строки с проверкой
Vladimir SitnikovЕсли делать проверку, делать её нужно правильно. Если вы не меняли уровень изоляции транзакций (который по-умолчанию равен read commited), то, может случиться так, что между вашей проверкой и следующим действием кто-то такую строку добавит (== insert может вернуть duplicate key exception даже после проверки "if not found").

Поэтому, в коде триггера trgf_b_trick _нужно_ обрабатывать duplicate key в случае insert'а (в данном случае, можно просто проигнорировать это исключение)

Я только набросал идею, а вообще ты прав.
Если поправить триггер, то выйдет так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE OR REPLACE FUNCTION trgf_b_trick()
RETURNS TRIGGER AS $BODY$
DECLARE
  vi_aid INTEGER;  -- будем тут тримати наш aid, якщо треба буде вставити
BEGIN
  BEGIN
    INSERT INTO a(name) VALUES (NEW.col1);
  EXCEPTION WHEN UNIQUE_VIOLATION THEN
    NULL;  -- ідем дальше
  END;
  
  SELECT aid
    INTO vi_aid
    FROM a
   WHERE a.name = NEW.col1;

  NEW.col1 := vi_aid::varchar;  -- то шо витягнули з a (в varchar)

  RETURN NEW;
END;
$BODY$ LANGUAGE PLpgSQL;

___________________
Sorry for my Russian
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставка строки с проверкой / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]