The skeletons of the tables involved look like this:
CREATE TABLE Orders
(order_nbr INTEGER NOT NULL PRIMARY KEY,
customer_duns_nbr CHAR(9) NOT NULL
REFERENCES Companies (duns_nbr),
…);
CREATE TABLE Order_Details
(order_nbr INTEGER NOT NULL
REFERENCES Orders(order_nbr)
ON UPDATE CASCADE
ON DELETE CASCADE,
item_nbr INTEGER NOT NULL,
PRIMARY KEY (order_nbr, item_nbr)
specifier_duns_nbr CHAR(9) NOT NULL,
REFERENCES Companies (duns_nbr),
…);
What is the best way to enforce the constraint which we could write in
Full-92 as a table constraint:
CHECK (specifier_duns_nbr
IN ((SELECT customer_duns_nbr
FROM Orders AS O
WHERE O.order_nbr = Order_Details.order_nbr),
'999999999')
I can only think of two ways (you might notice the absence of good :-)
either via triggers, or by adding a dummy order for your company and
use a foreign key. In the latter case I would then add check
constraints in referencing tables that prevents the usage of this
dummy order other than for specifier_duns_nbr.
/Lennart
create table Order_Details (
order_nbr int not null
references Orders(order_nbr)
on delete cascade
, item_nbr int not null
, specifier_duns_nbr char(9)
...
, primary key (order_nbr, item_nbr)
, foreign key (order_nbr, specifier_duns_nbr)
references Orders(order_nbr, customer_duns_nbr)
on delete cascade
);
---
Sincerely,
Mark B.
Maybe one of those will help,
Chris
CREATE TABLE Order_Details
(order_nbr INTEGER NOT NULL
REFERENCES Orders(order_nbr)
ON UPDATE CASCADE
ON DELETE CASCADE,
item_nbr INTEGER NOT NULL,
PRIMARY KEY (order_nbr, item_nbr)
specifier_duns_nbr CHAR(1) DEFAULT 'C' NOT NULL
CHECK(specifier_duns_nbr IN ('C', 'U')),
…);
Where C = customer and U = Us in the specifier_duns_nbr. Then we make
a VIEW of Order_Details with a CASE expression :
CASE specifier_duns_nbr
WHEN 'U' THEN '999999999'
WHEN 'C' THEN (SELECTcustomer_duns_nbr
FROM Orders AS O
WHERE O.order_nbr =
Order_Details.order_nbr)
ELSE NULL END
and add an INSTEAD OF TRIGGER and we are done.