powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставка строки с проверкой
10 сообщений из 10, страница 1 из 1
Вставка строки с проверкой
    #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
Вставка строки с проверкой
    #34552615
ilejn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, возможно, торможу (все-таки вечер пятницы), но более красивого решения, чем банальный триггер я здесь не вижу. Начать, соответственно, с изучения триггеров.
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #34552902
Vladimir Sitnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-=Koba=-БД должна проверить если в таблице A в колонке name строка с Example111 и возратить ее AID если нету то соотвественно создать новую запись и возратить ее AID

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

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

Триггеры здесь не к месту.
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #34552906
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так что здесь будет лучше
Я уже 2 часа над тригерами потею
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #34552959
Vladimir Sitnikov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-=Koba=-уже 2 часа над тригерами потеюconstraint создали?
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #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
Вставка строки с проверкой
    #34553113
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо. пошел применять
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #34553235
serejaa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vladimir Sitnikov -=Koba=-БД должна проверить если в таблице A в колонке name строка с Example111 и возратить ее AID если нету то соотвественно создать новую запись и возратить ее AID

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

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

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


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

или проверка в триггере , есть ли уже такая запись ?
...
Рейтинг: 0 / 0
Вставка строки с проверкой
    #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
Вставка строки с проверкой
    #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
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставка строки с проверкой
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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