PostgreSQL создает поля, которые оба поля не могут повторять - PullRequest
0 голосов
/ 03 июля 2019

Учитывая таблицу, пожалуйста, сообщите нам, как установить уникальное ограничение, чтобы first_name и last_name не могли вводить одно и то же поле?

CREATE TABLE app_user (
   id serial PRIMARY KEY,
   first_name VARCHAR (50),
   last_name VARCHAR (50),
   email VARCHAR (50) UNIQUE
);


CREATE UNIQUE INDEX user_firstname_last_name_id ON app_test.app_user(first_name text_ops,last_name text_ops);

Я создал уникальное ограничение, включая (имя, фамилия), но безрезультатно.

Если first_name - «Chan», last_name - «Mandy», триггеры базы данных позволяют обновлять эту запись

Если first_name - «Chan», last_name - «Chan», база данных запускаетсяне позволяет обновлять эту запись

Что касается вставки в первый раз, проверку ограничения можно игнорировать

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Используйте проверочное ограничение , если вы хотите, чтобы два столбца не содержали одинаковые значения, например,

CREATE TABLE app_user (
   id serial PRIMARY KEY,
   first_name VARCHAR (50),
   last_name VARCHAR (50),
   email VARCHAR (50) UNIQUE,
   CHECK(first_name <> last_name)
);

insert into app_user (first_name, last_name)
values('Adam', 'Adam');

ERROR:  new row for relation "app_user" violates check constraint "app_user_check"
DETAIL:  Failing row contains (2, Adam, Adam, null).
0 голосов
/ 04 июля 2019

Проверочные ограничения применяются ко всем операциям таблицы DML (скважина Insert и Update). То, что вы хотите, не может быть сделано с ограничениями. Вы можете сделать это с помощью триггера.

CREATE TABLE app_user (
   id serial PRIMARY KEY,
   first_name VARCHAR (50),
   last_name VARCHAR (50),
   email VARCHAR (50) UNIQUE
); 

create or replace function reject_same_name()
returns trigger
language plpgsql
as $$
begin 
    if old.first_name = old.last_name then
       raise exception 'Cannot update row when first name and last name are the same.';
    end if;
    return new;
end ;
$$;

insert into app_user (first_name, last_name)
values('Adam', 'Adam');
-- 1 row 

insert into app_user (first_name, last_name)
values ('Sam','Henery');
-- 1 row 
select * from app_user;

update app_user
   set email = first_name || '.' || last_name || '@mydb.com' 
 where first_name = 'Sam'; 
-- 1 row updated

update app_user
   set email = first_name || '.' || last_name || '@mydb.com' 
 where first_name = 'Adam';  -- Is this really what we want??
********** Error **********

ERROR: Cannot update row when first name and last name are the same.
SQL state: P0001

Пока все хорошо? Но что происходит, когда мы понимаем, что была допущена ошибка: как будто фамилия была введена неправильно, поэтому мы исправляем:

update app_user set last_name = 'Smith' 
  where last_name = 'Adam';

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...