SQL add a new column and its values only can be in several fixed options - sql

I want to add a new column with SQL in my data table as below,
CREATE TABLE brands (
Brand varchar(255),
Contact varchar(150),
Address varchar(255),
Location varchar(50),
)
:
I wish to add a new column called country, and the value only can be selected from the following values: "Japan", "New Zealand", "US", "France"
I can add the new column but I don't know how to set the limited optional values for the column. Please help if you have ideas. Many thanks

You could use a check constraint, or a foreign key.
Check constraint:
alter table brands add country_name varchar(64) not null;
alter table brands add constraint ck_country_list
check (country_name in ('Japan', 'New Zealand', 'US', 'France'));
With a check constraint, the values that are allowed never change (unless you change the constraint code). With a foreign key, the allowed values are stored in another table. As long as the value exists in the other table, they are allowed in this table.
create table countries(country_name varchar(64) not null primary key);
insert countries (country_name)
values ('France'), ('New Zealand') -- etc
alter table brands add country_name varchar(64) not null;
alter table brands add constraint fk_brands_countries
foreign key (country_name) references countries (country_name);
But we can actually do even better that! Countries already have a well defined "thing" which uniquely identifies them: ISO3166 country codes. You can use the 2 char, 3 char, or int versions. Using well defined standards where you can is always a good idea for primary keys.
This is the next level up beyond what you are currently trying to learn. But here's what it might look like:
create table countries
(
country_code char(2) not null primary key clustered,
country_name varchar(64) not null
);
insert countries (country_code, country_name)
values ('FR', 'France'), ('NZ', 'New Zealand') -- etc etc;
alter table brands add country_code char(2) not null;
alter table brands add constraint fk_brands_countries
foreign key (country_code) references countries (country_code);
When you want to get the country name, you join the brands table to the countries table using the country_code column.

After you added the column you could add a check constraint
ALTER TABLE brands
ADD CONSTRAINT chk_country check (Country IN ('Japan', 'New Zealand', 'US', 'France'));

Related

I have come across an error in SQL and cannot fix this foreign key error. See desc for more information

I have been receiving the error code 1452, i am trying to add keys to a table to keep data unqiue and useable in other tables. i have created the tables and can use the information already entered but i want to make the databases properly so i am trying to use the keys. please refer to the code below.
CREATE TABLE CUSTOMERS (
CustID varchar(50) NOT NULL,
Client_Name varchar(50) NOT NULL,
Client_Address varchar(80) NOT NULL,
PRIMARY KEY (CustID)
);
CREATE TABLE ORDERS (
Order_ID VARCHAR(10) NOT NULL,
Client_NameID varchar(50) NOT NULL,
Dates varchar(10) NOT NULL,
PRIMARY KEY (Order_ID),
FOREIGN KEY (Client_NameID) REFERENCES CUSTOMERS(CustID)
);
SELECT * FROM CUSTOMERS;
SELECT * FROM ORDERS;
DESCRIBE Orders; /*Used to display the Table*/
ALTER TABLE ORDERS ADD Dates VARCHAR(10); /*Used to add columns into the table*/
ALTER TABLE ORDERS DROP COLUMN Date; /*Used to remove column from the table*/
INSERT INTO CUSTOMERS (CustID, Client_Name, Client_Address) VALUES
('168', 'Coventry Building Services', 'Units 2-4, Binley Industrial Estate, CV3 2WL'), /*Used to insert values into the columns*/
('527', 'Allied Construction LTD', '34, Lythalls La Industrial Estate, NG18 5AH'),
('169', 'Ricoh Builds Ltd', 'Unit 12, Stoneleigh Park, CV8 2UV'),
('32', 'British Embassy in Tehran', '198 Ferdowski Avenue Tehran 11316-91144 Iran');
INSERT INTO ORDERS (Order_ID, Client_NameID, Dates) VALUES
('CON-2237', 'Coventry Building Services', '2014-12-14'),
('CON-3664', 'Allied Construction LTD', '2015-01-16'),
('CON-2356', 'Ricoh Builds Ltd', '2015-02-12'),
('CON-1234', 'British Embassy in Tehran', '2015-04-16');
DELETE FROM ORDERS WHERE Client_Name='Coventry Building Services'; /*Used to delete specific
data from the specific row and column wherever applicable*/
DROP TABLE CUSTOMERS;
DROP TABLE ORDERS;
Below are the tables im trying to work with, all of them will pretty much have a key that links them together if necessary
The CustomerS Table which only includes a Primary Key
The Orders Table which includes a Primary and Foreign key
The problem is with the inserts into table orders. Your foreign key on Client_NameIDreferencesCUSTOMERS(CustID), but you are giving the CUSTOMERS(Client_Name) instead.
You probably want:
INSERT INTO ORDERS (Order_ID, Client_NameID, Dates) VALUES
('CON-2237', 'CON-2237', '2014-12-14');
('CON-3664', 'CON-3664', '2015-01-16');
('CON-2356', 'CON-2356', '2015-02-12');
('CON-1234', 'CON-1234', '2015-04-16');
Notes:
You can perform all inserts in a single query by passing several tuples of values, as shown above
Don't store dates as strings; instead, use the date datatype, which exists for that purpose. I changed the query so it uses proper date literals, which would fit in a date column
it is unclear why you want to use the same value for the primary key of customers and orders - to me, this makes things harder to follow. I would recommend just using auto-incremented primary keys

No row selected

SQL> create table artwork
2 (
artwork_id number(7) NOT NULL,
barcode char(20),
title char(20),
description char(50),
PRIMARY KEY (artwork_id)
);
Table created.
SQL> select * from artwork;
no rows selected
I created the table but it showing me this error dont know. Why table it not showing?
I would expect the create to look like this:
create table artwork (
artwork_id number primary key,
barcode char(20),
title varchar2(20),
description varchar2(50)
);
Notes:
There is no need to have number(7). You can specify the length, but it is not necessary.
For title and description you definitely want varchar2(). There is no reason to store trailing spaces at the end of a name.
That may be the same for barcode, but because it might always be exactly 20 characters or trailing spaces might be significant, you might leave it as char().
The primary key constraint can be expressed in-line. There is no need for a separate declaration.
You probably simply want something like
create table artwork
(
artwork_id number(7) NOT NULL,
barcode varchar2(20),
title varchar2(20),
description varchar2(50),
PRIMARY KEY (artwork_id)
);
insert into artwork values (0, 'barcode', 'fancytitle', 'somedescription');
insert into artwork values (1, 'barcode1', 'fancytitle1', 'somedescription1');
select * from artwork;
This creates a table "ARTWORK", inserts 2 rows in it and then selects all rows currently in the table.
An empty table contains no data, with the create table-statement you only define the bucket of data, you have to fill the bucket as well with items.
I'd also recommend a auto increment column (oracle 12c) or a trigger/sequence to increment the id automatically. But that's something to read later :)

How do I check the value of a foreign key on insert?

I'm teaching myself SQL using Sqlite3, well suited for my forever-game project (Don't we all have one?) and have the following tables:
CREATE TABLE equipment_types (
row_id INTEGER PRIMARY KEY,
type TEXT NOT NULL UNIQUE);
INSERT INTO equipment_types (type) VALUES ('gear'), ('weapon');
CREATE TABLE equipment_names (
row_id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE);
INSERT INTO equipment_names (name) VALUES ('club'), ('band aids');
CREATE TABLE equipment (
row_id INTEGER PRIMARY KEY,
name INTEGER NOT NULL UNIQUE REFERENCES equipment_names,
type INTEGER NOT NULL REFERENCES equipment_types);
INSERT INTO equipment (name, type) VALUES (1, 2), (2, 1);
So now we have a 'club' that is a 'weapon', and 'band aids' that are 'gear'. I now want to make a weapons table; it will have an equipment_id that references the equipment table and weapon properties like damage and range, etc. I want to constrain it to equipment that is a 'weapon' type.
But for the life of me I can't figure it out. CHECK, apparently, only allows expressions, not subqueries, and I've been trying to craft a TRIGGER that might do the job, but in short, I can't quite figure out the query and syntax, or how to check the result that as I understand it will be in the form of a table, or null.
Also, are there good online resources for learning SQL more advanced than W3School? Add them as a comment, please.
Just write a query that looks up the type belonging to the new record:
CREATE TRIGGER only_weapons
BEFORE INSERT ON weapons
FOR EACH ROW
WHEN (SELECT et.type
FROM euqipment_types AS et
JOIN equipment AS e ON e.type = et.equipment_type_id
WHERE e.row_id = NEW.equipment_id
) != 'weapon'
BEGIN
SELECT RAISE(FAIL, "not a weapon");
END;
The foreign key references should be to the primary key and to the same time. I would phrase this as:
CREATE TABLE equipment_types (
equipment_type_id INTEGER PRIMARY KEY,
type TEXT NOT NULL UNIQUE
);
INSERT INTO equipment_types (type) VALUES ('gear'), ('weapon');
CREATE TABLE equipment_names (
equipment_name_id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
INSERT INTO equipment_names (name) VALUES ('club'), ('band aids');
CREATE TABLE equipment (
equipment_id INTEGER PRIMARY KEY,
equipment_name_id INTEGER NOT NULL UNIQUE REFERENCES equipment_names(equipment_name_id),
equipement_type_id INTEGER NOT NULL REFERENCES equipment_types(equipement_type_id)
);
I would not use the name row_id for the primary key. That is the built-inn default, so the name is not very good. In SQLite, an integer primary key is automatically auto-incremented (see here).

How to CREATE TABLE with disjoint relationship in SQL

I am trying to create a table using a disjoint subtype relationship.
For example, if the Supertype is furniture, and I have 3 Subtypes of furniture: chair, couch, and table.
Then:
CREATE TABLE Furniture
(order_num NUMBER(15), desc VARCHAR2(20), type VARCHAR2(10));
How do I make an option to pick type of chair, couch or table?
You can use REFERENCES in the CREATE TABLE.
CREATE TABLE Furniture_SubTypes
(
sub_type VARCHAR(10) PRIMARY KEY
);
INSERT INTO Furniture_SubTypes VALUES ('Chair');
INSERT INTO Furniture_SubTypes VALUES ('Couch');
INSERT INTO Furniture_SubTypes VALUES ('Table');
CREATE TABLE Furniture
(
order_num NUMBER,
description VARCHAR(20),
sub_type REFERENCES Furniture_SubTypes(sub_type)
);
Use a check constraint:
CREATE TABLE Furniture (
order_num NUMBER(15),
description VARCHAR2(20),
type VARCHAR2(10),
check (type in ('chair', 'couch', 'table'))
);
Note that desc is a poor choice for a column name, because it is a keyword in SQL (used for order by).

need help in primary key and foreign key

I need help in auto populating the primary key values in foreign key table while inserting data in foreign key table. For Example: I have created table:
create table Patient
(
PatientId int IDENTITY(1,1) primary key,
FirstName varchar(50),
SurName varchar(50),
Gender char(20),
)
Say 5 rows are there in this Patient Table:
Say First Row value is: 1, Priya, Kumari, Female
I have created the Guardians Table:
create table Guardians
(
GuardiansId int identity(1,1) primary key,
PatientId int foreign key references Patient(PatientId),
FirstName varchar(50),
SurName varchar(50),
Gender char(20),
RelationToPatient varchar(50),
)
In this table Insert operations are like this:
insert into Guardians(FirstName, SurName, Gender,RelationToPatient)values('Sumit','Kumar','Male','Wife')
While selecting the Guardians Table PatientId showing NULL values: My query is while inserting the values in Guardians Table PatientId should be auto Populated which will come from Patient Table...
My second problem is: How to create the Identity column as varchar. For example: suppose I want to increment my Guardians Table with 'GRD0001', 'GRD0002', 'GRD0003' like this...
Thanks,
S.D
Your question is not very clear - what exactly do you want to do??
When you insert something into the Guardians table, you want to automatically also insert it into the Patients table? I don't quite follow. Can you make a complete example, maybe??
If you need to capture the insert IDENTITY value from the Patient table, do this:
DECLARE #NewPatientID INT
INSERT INTO dbo.Patient(fields) VALUES(.......)
SET #NewPatientID = SCOPE_IDENTITY()
INSERT INTO dbo.Guardians(PatientId, ......) VALUES(#NewPatientID, ......)
As for your second question: leave you GuardiansId IDENTITY as it is (only an INT column can be an IDENTITY and you want to keep that - trust me!) and add a computed column to your table:
ALTER TABLE dbo.Guardians
ADD GuardianIDWithPrefix AS
'GDR' + RIGHT('0000' + CAST(GuardiansId AS VARCHAR(4)), 4) PERSISTED
Since it's a PERSISTED field, you can even index on it and use it like a normal field in every respect.
That should do the trick!