0

Given table, would you please us how to set up the unique constraint so that first_name and last_name are not allowed to type the same field?

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);

I have created unique constraint including (first_name, last_name) but to no avail.

If first_name is 'Chan' , last_name is 'Mandy' , the database triggers allows this record to be updated

If first_name is 'Chan' , last_name is 'Chan' , the database triggers does not allow this record to be updated

As for insert first time, the constraint check can be ignored

5
  • Question Edited . It is the table user Commented Jul 3, 2019 at 17:31
  • user is a reserved word(postgresql.org/docs/8.1/sql-keywords-appendix.html). Commented Jul 3, 2019 at 17:32
  • no longer user now . It is app_user Commented Jul 3, 2019 at 17:34
  • The code is fine. Commented Jul 3, 2019 at 17:35
  • Edited, Here is the case Commented Jul 3, 2019 at 17:44

2 Answers 2

1

Use a check constraint if you want the two columns not to contain the same values, e.g.

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).
Sign up to request clarification or add additional context in comments.

2 Comments

How can we apply check only if the user record is UPDATE instead of INSERT?
The check constraint applies to the table, not to statements. It works both when inserting and updating rows.
0

Check constraints apply to all table DML operation (well Insert and Update) enteries. So what you want cannot be done with constraints. You can accomplish it with trigger.

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

So far so good? But what happens when we realize an mistake was made: Like the last name was inserted incorrectly so we correct to:

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

So that trigger function may need lots of work deciding the business rule as to what can and what cannot be updated and when. Triggers are really a bad ways to enforce business rules.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.