I am trying to create a simple database where I have a table of customer data and a table of order data. I am trying to write a constraint that makes it so a customer can’t order more than a specific amount of items on a given day. Here’s what I have:
CREATE TABLE CUSTOMER
(
CUSTOMER_NUM CHAR(3) PRIMARY KEY,
CUSTOMER_NAME CHAR(35) NOT NULL,
STREET CHAR(15),
CITY CHAR(15),
STATE CHAR(3),
ZIP CHAR(5),
);
CREATE TABLE ORDERS
(
ORDER_NUM CHAR(5) PRIMARY KEY,
ORDER_DATE DATE,
CUSTOMER_NUM CHAR(3),
CONSTRAINT CUSTOMER_NUM_FKEY FOREIGN KEY (CUSTOMER_NUM)
REFRENCES CUSTOMER (CUSTOMER_NUM) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
);
And this is what I wrote to enforce this constraint but it does not work. I assume its because ORDER_NUM and ORDER_DATE never have equal values.
CREATE ASSERTION ITEM_LIMIT
CEHCK(
( SELECT COUNT(*)
FROM CUSTOMER C1, ORDERS O1
WHERE C1.CUSTOMER_NUM = O1.CUSTOMER_NUM AND
O1.ORDER_DATE = O1.ORDER_NUM
) <= 1000
My question is how to get this constraint to work, like how to I limit the amount of orders per day.
As @ruakh already cleared up, there is no
CREATE ASSERTIONin PostgreSQL. Just check the list of SQL commands. It’s not there.You can use triggers that update a count per customer combined with a
CHECKconstraint, but you have to cover all relevant DML statements: INSERT, UPDATE, DELETE. Could look like this:Prepare existing customer table:
Create trigger functions and triggers:
I made all those triggers AFTER triggers – that’s why it is ok to
RETURN NULL. AFTER is preferable to BEFORE in this case. It performs better if any other conditions could cancel DML statements in the middle (like other triggers).If you have nothing of the sort, then BEFORE triggers may be preferable. Be sure to make the trigger functions RETURN NEW / OLD accordingly in this case.