Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I enforce a constraint only if a column is not null in Postgresql?

I would like a solution to enforce a constraint only if a column is not null. I can't seem to find a way to do this in the documentation.

create table mytable(
  table_identifier_a INTEGER,
  table_identifier_b INTEGER,
  table_value1,...)

Do to the nature of the data, I will have identifier b and a value when the table is created. After we receive additional data, I will be able to populate identifier a. At this point I would like to ensure a unique key of (identifier_a, value1) but only if identifier_a exists.

Hopefully that makes sense, Any one have any ideas?

like image 683
Sheldon Ross Avatar asked Feb 23 '09 22:02

Sheldon Ross


People also ask

Which constraint makes sure that a column does not hold NULL value?

The NOT NULL constraint enforces a column to NOT accept NULL values. This enforces a field to always contain a value, which means that you cannot insert a new record, or update a record without adding a value to this field.

How do I deal with NOT NULL in PostgreSQL?

In PostgreSQL, we can add the NOT NULL Constraint to a column of an existing table with the ALTER TABLE command's help. The below illustrations of the ALTER TABLE command are used to add a NOT NULL constraint into the existing table: ALTER TABLE table_name. ALTER COLUMN column_name.

How do I make a column NOT NULL in PostgreSQL?

To add a not-null constraint, which cannot be written as a table constraint, use this syntax: ALTER TABLE products ALTER COLUMN product_no SET NOT NULL; The constraint will be checked immediately, so the table data must satisfy the constraint before it can be added.

How do you check if a column is NOT NULL in Postgres?

Here is an example of how to use the PostgreSQL IS NOT NULL condition in a SELECT statement: SELECT * FROM employees WHERE first_name IS NOT NULL; This PostgreSQL IS NOT NULL example will return all records from the employees table where the first_name does not contain a null value.


2 Answers

Ummm. Unique constraints don't prevent multiple NULL values.

CREATE TABLE mytable (
    table_identifier_a   INTEGER    NULL,
    table_identifier_b   INTEGER    NOT NULL,
    table_value1         INTEGER    NOT NULL,

    UNIQUE(table_identifier_a, table_identifier_b)
);

Note that we can insert muliple NULLs into it, even when identifier_b matches:

test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# select * from mytable;
 table_identifier_a | table_identifier_b | table_value1 
--------------------+--------------------+--------------
                    |                  1 |            2
                    |                  1 |            2
(2 rows)

But we can't create duplicate (a,b) pairs:

test=# update mytable set table_identifier_a = 3;
ERROR:  duplicate key value violates unique constraint "mytable_table_identifier_a_key"

Of course, you do have an issue: Your table has no primary key. You probably have a data model problem. But you didn't provide enough details to fix that.

like image 168
derobert Avatar answered Sep 18 '22 23:09

derobert


If it is feasible to complete the entire operation within one transaction, it is possible to change the time which postgres evaluates the constraint, i.e.:

START;
SET CONSTRAINTS <...> DEFERRED;
<SOME INSERT/UPDATE/DELETE>
COMMIT;

In this case, the constraint is evaluated at commit. See: Postgres 7.4 Doc - Set constraints or Postgres 8.3 Doc

like image 22
Dana the Sane Avatar answered Sep 18 '22 23:09

Dana the Sane