Reusing a constraint while creating a table - sql

While creating a table how can I reuse a constraint that has been mentioned for a previous column?
create table ticket_details(
from_stn char(3)
constraint chk check(from_stn in ('vsh','mas','ndl'))
constraint nn NOT NULL,
to_stn char(3)
constraint nn1 NOT NULL, (instead of crea)
seat_no number(3)
constraint PK primary key,
);

A domain constraint will be enforced on any instance of the domain. Also: upon change, you'll have to change it in only one place. (the syntax might differ slightly between implementations)
CREATE DOMAIN THE_STN CHAR(3) constraint THE_STN_check_da_value check(VALUE in ('vsh','mas','ndl'))
;
CREATE table ticket_details
( seat_no INTEGER NOT NULL PRIMARY KEY
, from_stn THE_STN NOT NULL
, to_stn THE_STN
);
INSERT INTO ticket_details(seat_no,from_stn,to_stn) VALUES (1, 'vsh', 'ndl' ); -- succeeds
INSERT INTO ticket_details(seat_no,from_stn,to_stn) VALUES (2, 'vsh', NULL ); -- succeeds
INSERT INTO ticket_details(seat_no,from_stn,to_stn) VALUES (2, 'lol', 'mas' ); -- fails

Reusing a constraint for another column is not possible. You have to define it for other column if you want

Related

Creating a SQL database script for fictional restaurant

im making a fictional database for a ficitonal restaurant. I managed to write most of SQL script myself and it works. Like creating tables, inserting fake data. However I am not sure how to connect a meal to an order and table, and bill to a meal, and all of that to a customer.
Here is my script (the commented out foreign keys are what i dont know how to connect, or how to edit them so its all connected as i mentioned above):
DROP DATABASE IF EXISTS restaurantDB;
CREATE DATABASE restaurantDB;
USE restaurantDB;
CREATE TABLE `bill` (
`billID` int NOT NULL AUTO_INCREMENT,
`payAmount` varchar(6) NOT NULL,
PRIMARY KEY (`billID`)
);
INSERT INTO `bill` VALUES (1, '$258');
CREATE TABLE `customer` (
`customerID` int NOT NULL AUTO_INCREMENT,
`firstName` varchar(255) NOT NULL,
`lastName` varchar(255) NOT NULL,
`phone` varchar(20) NOT NULL,
PRIMARY KEY (`customerID`)
);
INSERT INTO `customer` VALUES (1, 'Bruce', 'Lee', '420420589');
CREATE TABLE `meal` (
`mealID` int NOT NULL AUTO_INCREMENT,
`sides` varchar(255) NULL,
`main` varchar(255) NULL,
`beverage` varchar(255) NOT NULL,
PRIMARY KEY (`mealID`)
);
INSERT INTO `meal` VALUES (1, 'potatos', 'steak', 'wine');
CREATE TABLE `order` (
`orderID` int NOT NULL,
`time` datetime(2) NOT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`orderID`)
);
INSERT INTO `order` VALUES (1, '21-09-27 13:36:06');
CREATE TABLE `reservation` (
`reservationID` int NOT NULL AUTO_INCREMENT,
`checkIn` datetime(2) NOT NULL,
`checkOut` datetime(2) NOT NULL,
PRIMARY KEY (`reservationID`)
);
INSERT INTO `reservation` VALUES (1, '21-09-27 13:24:06', '21-09-27 14:17:23');
CREATE TABLE `table` (
`tableID` int NOT NULL AUTO_INCREMENT,
`numOfSeats` int NOT NULL,
PRIMARY KEY (`tableID`)
);
INSERT INTO `table` VALUES (1, 1);
/* ALTER TABLE `table` ADD CONSTRAINT `fk_bill_table_1` FOREIGN KEY (`tableID`) REFERENCES `table` (`billID`);
ALTER TABLE `order` ADD CONSTRAINT `fk_order_table_1` FOREIGN KEY (`orderID`) REFERENCES `table` (`tableID`);
ALTER TABLE `order` ADD CONSTRAINT `fk_order_meal_1` FOREIGN KEY (`orderID`) REFERENCES `meal` (`mealID`);
ALTER TABLE `order` ADD CONSTRAINT `fk_order_bill_1` FOREIGN KEY (`orderID`) REFERENCES `bill` (`billID`);
ALTER TABLE `reservation` ADD CONSTRAINT `fk_reservation_customer_1` FOREIGN KEY (`reservationID`) REFERENCES `customer` (`customerID`);
ALTER TABLE `table` ADD CONSTRAINT `fk_table_reservation_1` FOREIGN KEY (`tableID`) REFERENCES `reservation` (`reservationID`); */
Here is also a picture of the diagram (not sure if it makes sense connected like i have it currently tho):
Thanks to anyone who will be able to explain and help make the connections.
Okay, so finally got it working. Thanks #Austin.
Actually the only issue I had was with the datetime(2) it was just supposed to say datetime.
However #Austin showed me a better alternative, so I will create also a second, extended database with the relations #Austin suggested and add onto that.

Insert empty string value in a foreign key field

I have an error when trying to insert values with a '' in the foreign key field.
I use PostgreSQL v10.
My sql code:
CREATE TABLE meas_name (
nopol varchar(2) NOT NULL,
cchim varchar(10) NOT NULL,
ncon varchar(30) NOT NULL,
PRIMARY KEY (nopol)
);
CREATE TABLE main_device (
ntypapp smallint NOT NULL,
no_main smallint NOT NULL,
lib_main varchar(25),
nopol varchar(2),
no_chrono smallint,
PRIMARY KEY (no_main,ntypapp)
);
ALTER TABLE main_device ADD CONSTRAINT fk_maindevice_measname FOREIGN KEY (nopol) REFERENCES meas_name(nopol) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE;
When i insert something in measure with a known deviceno I have this error:
insert into main_device values
(1, 1, 'TST LASER','',1578)
ERROR: insert or update on table « main_device » violates foreign key constraint « fk_maindevice_measname »
DETAIL: Key (nopol) = () is not present in table « meas_name ».
I have tested it on: https://www.db-fiddle.com/f/fBnNSYWU8qZwFbmEoU5dce/1
There was no issue on Oracle database, but I don't know much about Postgres, Is there any limitation? How can I manage this?
An empty string is not NULL. Use NULL:
insert into main_device (ntypapp, no_main, lib_main, nopol, no_chrono)
values (1, 1, 'TST LASER', NULL, 1578);
A NULL value does not need to match the foreign key constraint (in this context, NULL means "no value"). However, an empty string is a valid value and the database expects a matching row in the referenced table.
I also added the explicit column names because that is a best-practice.

SQL ORA-02291: integrity constraint violated - parent key not found

I have encountered some problem with SQL foreign key.
Here are my table and insert SQL.
create table passenger_card2
(
phone char(20) primary key,
name char(20)
);
create table card
(
card_num char(20) primary key,
balance number(10,2),
cvn char(20)
);
create table passenger_card1
(
sin integer primary key,
user_id char(20) not null unique,
phone char(20),
card_num char(20) unique,
foreign key(phone) references passenger_card2,
foreign key (card_num) references card
);
And here are my INSERT statements:
INSERT INTO PASSENGER_CARD2 VALUES ( '111222333' , 'Ace');
INSERT INTO CARD VALUES ( '1000' , '100.1' , '110');
INSERT INTO PASSENGER_CARD1 VALUES ('100', 'aaaa', '111222333', '1000');
However, I get an error when I tried to insert PASSENGER_CARD1 data:
SQL ORA-02291: integrity constraint violated - parent key not found
I am not sure why my foreign key is wrong?
I am not sure if this is going to be right but you should make the table 2 first before you create the first table. The database is confused because it wouldnt make sense telling them that theres gonna be a foreign key in the second table but the table isnt created. Run the code for the second table first and then run the code for the first table.

Unique constraint on two database columns with reverse direction

I'm stuck upon a following problem: Let's say I have a table with relations to itself:
CREATE TABLE ITEM (
ID NUMBER(18) PRIMARY KEY,
NAME VARCHAR2(100 CHAR) NOT NULL
);
ALTER TABLE ITEM ADD CONSTRAINT PK_ITEM PRIMARY KEY (ID);
CREATE TABLE ITEM_RELATION (
FIRST_ITEM_ID NUMBER(18) NOT NULL,
SECOND_ITEM_ID NUMBER(18) NOT NULL,
RELATION_TYPE VARCHAR2(1) NOT NULL
);
ALTER TABLE ITEM_RELATION ADD CONSTRAINT PK_ITEM_RELATION PRIMARY KEY (FIRST_ITEM_ID, SECOND_ITEM_ID, RELATION_TYPE);
--ALTER TABLE ITEM_RELATION ADD CONSTRAINT UK_ITEMS UNIQUE (FIRST_ITEM_ID, SECOND_ITEM_ID, RELATION_TYPE);
ALTER TABLE ITEM_RELATION ADD CONSTRAINT FK_FIRST_ITEM FOREIGN KEY (FIRST_ITEM_ID) REFERENCES ITEM(ID);
ALTER TABLE ITEM_RELATION ADD CONSTRAINT FK_SECOND_ITEM FOREIGN KEY (SECOND_ITEM_ID) REFERENCES ITEM(ID);
Now let's say, I wan't the relation to be directional, that is if item 1 has relation to item 2 of certain type, the item 2 shouldn't have the same relation to item 1.
That is, the following should not be permitted:
INSERT INTO ITEM (ID, NAME) VALUES (1, 'Item 1');
INSERT INTO ITEM (ID, NAME) VALUES (2, 'Item 2');
INSERT INTO ITEM_RELATION(FIRST_ITEM_ID, SECOND_ITEM_ID, RELATION_TYPE) VALUES (1, 2, 'R');
INSERT INTO ITEM_RELATION(FIRST_ITEM_ID, SECOND_ITEM_ID, RELATION_TYPE) VALUES (2, 1, 'R');
It means that the table ITEM_RELATION defines a direction of this connection, and it shouldn't be allowed to add a reversed relation.
Is it possible with Oracle DB?
You can do this with a unique index. In Oracle, you can use functions in indexes, so this will work:
create unique index unq_item_relation_3 on
item_relation(RELATION_TYPE ,
least(FIRST_ITEM_ID, SECOND_ITEM_ID),
greatest(FIRST_ITEM_ID, SECOND_ITEM_ID)
);
You could get the same effect with a check constraint, by requiring that FIRST_ITEM_ID be less than SECOND_ITEM_ID:
alter table item_relation add constraint chk_item_relation_2
check ((FIRST_ITEM_ID < SECOND_ITEM_ID);
However, this requires that the items be inserted in a particular order.

Model a Table that depends on a set of values in referenced table that can or not be present at the same time

I have a table 'medical_observations' that in one field references other table 'sypstoms_at_arriving' that describes a list of possible symptoms.
CREATE TABLE `patients`(
id_patient INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(25) ,
address VARCHAR(50) ,
CONSTRAINT `uc_Info_Patient` UNIQUE (`id_patient`)
);
INSERT INTO `patients` values (1,'joe','joe´s address');
INSERT INTO `patients` values (2,'moe','moe´s address');
INSERT INTO `patients` values (3,'karl','karle´s address');
INSERT INTO `patients` values (4,'lenny','lenny´s address');
CREATE TABLE `symptoms_at_arrival` (
symptom_at_arrival varchar(30) primary key
);
INSERT INTO `symptoms_at_arrival` values ('vomit');
INSERT INTO `symptoms_at_arrival` values ('urine');
INSERT INTO `symptoms_at_arrival` values ('dizziness');
INSERT INTO `symptoms_at_arrival` values ('convulsion');
CREATE TABLE `medical_observations`(
id_medical_observation INTEGER NOT NULL PRIMARY KEY,
id_patient INTEGER NOT NULL,
symptom_at_arrival VARCHAR(30),
FOREIGN KEY (id_patient) references `patients` (id_patient),
FOREIGN KEY (symptom_at_arrival) references `symptoms_at_arrival` (symptom_at_arrival ),
CONSTRAINT `uc_Info_medical_Observation` UNIQUE (`id_medical_observation`,`id_patient`)
);
My doubt is how to model or store th case when patient has several symptoms... and not just one.
If that would be the case the name of symptom would be enough...
But if patient show several symptoms at the same time?
Update
I have done a sqlfiddle, I was thinking to add a kind of table with 1's and 0's representing if patient shows certain symptom... Would that be correct?
You'll have to make connection in the foreign keys
|patient| |medical_observations| |symptoms_at_arriving|
--------- ---------------------- ----------------------
**id** 1 ----| **id_medical_observation** |-----1 **id**
name |-M **id_patient** | symptom_at_arrival
**symptom_at_arrival** M---|
Try this, don't have mysql here to test, making table multi primary key to support multiple symptoms at same time
CREATE TABLE `symptoms_at_arriving` (
id integer not null primary key autoincrement,
symptom_at_arrival varchar(30)
);
INSERT INTO `symptom_at_arrival' values ('vomit');
INSERT INTO `symptom_at_arrival` values ('urine');
INSERT INTO `symptom_at_arrival` values ('dizziness');
INSERT INTO `symptom_at_arrival` values ('convulsion');
CREATE TABLE `medical_observations`(
id_medical_observation INTEGER NOT NULL,
id_patient INTEGER NOT NULL,
symptom_at_arrival integer not null,
FOREIGN KEY (id_patient) references `patients` (id_patient),
FOREIGN KEY (symptom_at_arrival) references `symptoms_at_arriving` (symptom_at_arrival,
PRIMARY KEY (id_medical_observation, id_patient, symptom_at_arrival)
);