Checking column fill with CHECK

Asked

Viewed 74 times

0

I am creating the BD of my TCC and the table Clients is:

create table clients(
id serial primary key,
name varchar(255),
cpf varchar(11),
cnpj varchar(14),
....

I thought of doing a CHECK limiting the filling OR the CPF or the CNPJ, in case the 2 can never be empty.. obviously I’ll do it in the back, but I wanted a security in the comics too, how do I do it?

Thank you

2 answers

1

About the answer to my problem, I was able to solve it with the help of Diego Marques:

CREATE TABLE usuario(
id serial, 
cpf varchar(20),
cnpj varchar(20)
);
create or replace function cpfcnpjVerification() returns trigger language plpgsql as $$
begin
IF (NEW.cpf IS NULL AND NEW.cnpj IS NULL) THEN
  RAISE SQLSTATE '09000'
  USING MESSAGE = 'Column CPF and CNPJ cannot both be null';
END IF;

return NEW;
end $$;

create trigger InsertCpfCnpjNotNull before insert on usuario 
for each row execute procedure cpfcnpjVerification();

INSERT INTO usuario(cpf, cnpj) VALUES('22','33') -- normal
INSERT INTO usuario(cpf, cnpj) VALUES(NULL,'44') -- normal
INSERT INTO usuario(cpf, cnpj) VALUES('55',NULL) -- normal
INSERT INTO usuario(cpf, cnpj) VALUES(NULL,NULL) -- ERROR: Column CPF and CNPJ cannot both be null
                                                 --SQL state: 09000
                                                 --Context: PL/pgSQL function cpfcnpjverification() line 4 at RAISE

One question I was left was in relation to SQL STATE, which to use, but based on Postgres I chose the 09000 even though I don’t think it makes that much difference to me.

Thank you

1


Hello,

In your case, I know a solution with TRIGGER, follows below an example:

CREATE TABLE foo (
  FieldA INT,
  FieldB INT
);

DELIMITER //
CREATE TRIGGER InsertFieldABNotNull BEFORE INSERT ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
CREATE TRIGGER UpdateFieldABNotNull BEFORE UPDATE ON foo
FOR EACH ROW BEGIN
  IF (NEW.FieldA IS NULL AND NEW.FieldB IS NULL) THEN
    SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = '\'FieldA\' and \'FieldB\' cannot both be null';
  END IF;
END//
DELIMITER ;

INSERT INTO foo (FieldA, FieldB) VALUES (NULL, 10); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (10, NULL); -- OK
INSERT INTO foo (FieldA, FieldB) VALUES (NULL, NULL); -- gives error
UPDATE foo SET FieldA = NULL; -- gives error

Fiddle with the example: https://www.db-fiddle.com/f/5Hvg8qFvBEiGUimk9ySQab/0

For Postgresql just create a Trigger that returns NULL, ex:

create table stuff (
  stuff_id int primary key,
  thing text
);

create or replace function stuff_inserting() returns trigger language plpgsql as $$
begin

  return null;

end $$;

insert into stuff values (1, 'asdf');

select * from stuff; /* returns 1 row */

create trigger inserting before insert on stuff for each row execute procedure stuff_inserting();

insert into stuff values (2, 'fdsa');

select * from stuff; /* still returns only 1 row */
  • Ball show but in Postgres does not work correctly?

  • The logic works yes, just create a Trigger that returns null. I put an example of Trigger with null return in the answer.

  • I don’t know that part of triggers, I’ve never actually used it, although I know it’s very useful, but if you could give me a hand, I’d appreciate it. Obviously Postgres uses some different Mysql functions, but can you help me place a message? What I’ve done so far is: [https://www.db-fiddle.com/f/sJLeGX8tQybn4o87hnN8n1/0] This for Postgres worked here, it just didn’t return any messages because: USING MESSAGE = cpf || ' and ' || cnpf || ' cannot both be null'; Generates a message nothing to do, you have how to help me in this? Gracias

Browser other questions tagged

You are not signed in. Login or sign up in order to post.