oracle table creation - sql

The following code gives me ERROR at line 3: ORA-00907: missing right parenthesis:
CREATE TABLE ORGANISATION(
ORG_REF VARCHAR(5),
POSTCODE VARCHAR(10) FOREIGN KEY,
TELEPHONE NUMBER FOREIGN KEY,
DESCRIPTION VARCHAR(30),
AGENCY_ID VARCHAR(5));
Line 3 code is very annoying because looking at the line there are no spelling mistakes and everything is in the right place.

That's not how you define a foreign key. A foreign key must know how to find it's partner.
Read here: http://www.techonthenet.com/oracle/foreign_keys/foreign_keys.php
Foreign key definition goes something like this:
CREATE TABLE ORGANISATION(
ORG_REF VARCHAR(5),
POSTCODE VARCHAR(10), --THIS WILL BE FOREIGN KEY
TELEPHONE NUMBER, --2nd FOREIGN KEY
DESCRIPTION VARCHAR(30),
AGENCY_ID VARCHAR(5),
FOREIGN KEY FK_POSTCODE
REFERENCES other_table (post_code),
FOREIGN KEY FK_TELEPHONE
REFERENCES other_table2 (phone)
);
UPDATE:
Additional Recommended Reading: http://mattgemmell.com/2008/12/08/what-have-you-tried/

Where to start?
You should be using varchar2 not varchar. Although they're currently identical the future behaviour of varchar is not guaranteed
Telephone number as a numeric field? A lot of phone numbers start with a 0. You're losing this. If you ever want to display it nicely you have to do some funky string manipulation on exit.
If your IDs are numbers then you should store them as a number.
There is rarely a situation where a table should not have a primary key.
A foreign key is designed to enforce referential integrity in the database. There should therefore be one or two more tables in this schema as a minimum.
A typical situation might be like this, which assumes that the same postcode,phone combination exists in agency.
CREATE TABLE ORGANISATION(
ORG_REF VARCHAR2(5),
POSTCODE VARCHAR2(10) ,
TELEPHONE VARCHAR2(50),
DESCRIPTION VARCHAR(30),
AGENCY_ID VARCHAR(5),
CONSTRAINT PK_ORGANISATION PRIMARY KEY ( org_ref ),
CONSTRAINT FX_ORGANISATION FOREIGN KEY
REFERENCES SOME_OTHER_TABLE(POSTCODE,PHONE)
);
If it were just a single column and not 2 you could reference it inline, something like the following:
create table organisation (
org_ref number(16) not null
, phone varchar2(5) not null constraint fk_organisation
references agency ( phone )
, constraint pk_organisation primary key ( org_ref )
);
However, I doubt very much that this'll work. A foreign key must reference a unique constraint. So, judging by your comments you must have a table agency with a unique constraint or primary key on phone, postcode.
I suspect your data-model is flawed; it sounds as though organisation inherits from agency.
I would remove the phone and postcode from agency and just do a join to get that information, if you're currently looking at the agency table:
select a.*, o.postcode, o.phone
from agency a
join organisation o
on a.agency_id = o.agency_id
where a.id = 12345
Further reading:
Examples
Documentation

CREATE TABLE ORGANISATION(
ORG_REF VARCHAR(5),
POSTCODE VARCHAR(10),
TELEPHONE NUMBER,
DESCRIPTION VARCHAR(30),
AGENCY_ID VARCHAR(5),
constraint pcodefk foreign key(POSTCODE) references postalcodetable(POSTALCODE),
constraint telefk foreign key(TELEPHONE) references telephonenumbers(TELEPHONE));

Related

Number of referencing columns must match referenced columns

I am relatively new to SQL and I keep getting the following error "The number of columns in the foreign-key referencing list is not equal to the number of columns in the referenced list."
create table client
(name varchar(30),
phone int,
city varchar(20),
state char(2) CHECK(state='MN' OR state='ND' OR state='SD' OR state='WI' or state='IA'),
primary key(name,phone));
create table owns_vehicle
(name varchar(30),
phone int,
vin varchar(10),
primary key(name, phone, vin),
foreign key(name,phone) references client);
create table service_appointment
(mydate date,
vin varchar(10),
mechanic varchar(15),
description varchar(30) NOT NULL,
cost int CHECK (cost>=0),
primary key(mydate,vin),
foreign key(vin) references owns_vehicle);
This is the line that is causing the issue:
foreign key(vin) references owns_vehicle);
Does anyone know why I am getting this error?
You try to reference owns_vehicle, thus you need to reference all of the tables PRIMARY KEY columns, which would be name, phone, vin. But your foreign key has only vin, thus there are two columns (name, phone) missing.
The primary key has three parts. You need to reference all of them. If you are going to use this model, then you need the other two components:
create table service_appointment (
mydate date,
name varchar(30),
phone int,
vin varchar(10),
mechanic varchar(15),
description varchar(30) NOT NULL,
cost int CHECK (cost>=0),
primary key(mydate,vin),
foreign key(name, phone, vin) references owns_vehicle (name, phone, vin)
);
However, I think you data model should change. VINs can change owners. People can change phone numbers. These don't seem like good components of a primary key.
If you assume that a vehicle can only have a single owner at a given time, you can make your current data model work by changing owns_vehicle to have a uniqueness constraint on VIN:
CREATE TABLE OWNS_VEHICLE
(NAME VARCHAR2(30),
PHONE INT,
VIN VARCHAR2(10),
CONSTRAINT PK_OWNS_VEHICLE
PRIMARY KEY(NAME, PHONE, VIN)
USING INDEX,
CONSTRAINT OWNS_VEHICLE_UQ1
UNIQUE(VIN)
USING INDEX,
CONSTRAINT OWNS_VEHICLE_FK1
FOREIGN KEY(NAME,PHONE) REFERENCES CLIENT(NAME, PHONE));

Missing Keyword in SQL Code on Foreign Keys unable to create the table

Trying to create a table with an SQL code, but I'm getting an error:
Missing keyword
in regards to the foreign key.
CREATE TABLE Staff
(
staffID VARCHAR(5) NOT NULL,
name VARCHAR(50),
position VARCHAR(30),
branchID VARCHAR(5),
PRIMARY KEY (staffID),
FOREIGN KEY (branchID) REFERENCES Branch ON UPDATE CASCADE
);
Unlike other RDBMS (such as MySQL for example), Oracle does not support the ON UPDATE clause in foreign keys. You would just need to remove that part of the declaration.
Try:
CREATE TABLE Staff (
staffID VARCHAR(5) NOT NULL,
name VARCHAR(50),
position VARCHAR(30),
branchID VARCHAR(5),
PRIMARY KEY (staffID),
FOREIGN KEY (branchID) REFERENCES Branch(branchID) --ON UPDATE CASCADE
);
Demo on DB Fiddle
The logic behind this Oracle behavior is that the referred column is not supposed to change, since it must be PRIMARY KEY (or a UNIQUE column). I believe that this limitation makes sense... they just don't want to give users enough rope to hang themselves with.

Are these FKs necessary -- and are they stopping me?

I'm having some difficulties with a database I'm creating for a summer camp, specifically with the PK and FK constraints. When I declare the FK constraint (e.g. FOREIGN KEY(PID) references Campers(CamperID)) I get an error running my code through pgAdmin (I'm using PostgreSQL). I understand that, for example, the Campers table is not yet created, and this is most likely part/all of the roadblock, however I feel like my FKs are still wrong somehow. To my understanding, a FK is a PK in another table -- but I feel like there is some redundancy or disconnect between my tables.
I've put the syntax for some of my CREATE statements below. I'm not sure if I'll get reprimanded for the quality of my (somewhat vague) question, but I feel a bit lost and would appreciate any help or advice. Thank you in advance!
DROP TABLE IF EXISTS People;
CREATE TABLE People (
PID VARCHAR(10) NOT NULL UNIQUE,
FName TEXT NOT NULL,
LName TEXT NOT NULL,
DOB DATE NOT NULL,
ArrivalDate DATE NOT NULL DEFAULT CURRENT_DATE,
DepartureDate DATE,
US_PhoneNum VARCHAR(11) NOT NULL,
StreetAddress VARCHAR(200) NOT NULL,
Sex GENDER NOT NULL,
ZIP VARCHAR(10) NOT NULL,
PRIMARY KEY(PID),
FOREIGN KEY(PID) REFERENCES Campers(CamperID),
FOREIGN KEY(PID) REFERENCES Counselors(CounselorID),
FOREIGN KEY(ZIP) REFERENCES Zip(ZIP)
);
DROP TABLE IF EXISTS Zip;
CREATE TABLE Zip (
ZIP VARCHAR(10) NOT NULL,
City TEXT NOT NULL,
State VARCHAR(2) NOT NULL,
PRIMARY KEY(ZIP)
);
DROP TABLE IF EXISTS Campers;
CREATE TABLE Campers (
CamperID VARCHAR(10) NOT NULL REFERENCES People(PID),
AgeGroup AGES NOT NULL,
CabinID VARCHAR(2) NOT NULL,
Bed BEDTYPES NOT NULL,
GroupID VARCHAR(3) NOT NULL,
PRIMARY KEY(CamperID),
FOREIGN KEY(CamperID) REFERENCES People(PID),
FOREIGN KEY(CabinID) REFERENCES Cabins(CabinID),
FOREIGN KEY(Bed) REFERENCES Beds(Bed),
FOREIGN KEY(GroupID) REFERENCES Groups(GroupID)
);
DROP TABLE IF EXISTS Counselors;
CREATE TABLE Counselors (
CounselorID VARCHAR(10) NOT NULL REFERENCES People(PID),
GroupID VARCHAR(3) NOT NULL,
CabinID VARCHAR(2) NOT NULL,
PRIMARY KEY(CounselorID),
FOREIGN KEY(GroupID) REFERENCES Groups(GroupID),
FOREIGN KEY(CabinID) REFERENCES Cabins(CabinID)
);
ERROR message for further clarification:
ERROR: relation "campers" does not exist
********** Error **********
ERROR: relation "campers" does not exist
SQL state: 42P01
There are more tables (obviously) which I can provide the create statements for, if needed.
You should really start here: Foreign key.
In the context of relational databases, a foreign key is a field (or
collection of fields) in one table that uniquely identifies a row of
another table.
What you are trying to do in your script is to create a circular link between People, Campers and Counselors. Having a Primary Key field also a Foreign Key mandates that IDs across all referenced tables are identical.
... and to create a Foreign Key the referenced table must already exist in the database. So you should start with the table that does not have any Foreign Keys and create tables that reference only those tables created previously. Alternatively you can create all tables without Foreign Keys and add them later, when all the tables are present.
... and to answer the question, Foreign Keys are never necessary, but they might help.

Cannot add foreign key constraint, composite PK and FK

CREATE TABLE HOSPITAL (
HOSP_CODE INT(3) NOT NULL,
HOSP_NAME VARCHAR(15),
HOSP_ADDRESS VARCHAR(15),
HOSP_PHONE VARCHAR(8),
HOSP_SUMBED INT(5),
PRIMARY KEY (HOSP_CODE)
);
CREATE TABLE WARD (
HOSP_CODE INT(3) NOT NULL,
WARD_CODE INT(3) NOT NULL,
WARD_NAME VARCHAR(20),
WARD_SUMBED INT(3),
PRIMARY KEY (HOSP_CODE, WARD_CODE),
FOREIGN KEY (HOSP_CODE) REFERENCES HOSPITAL(HOSP_CODE),
FOREIGN KEY (WARD_CODE) REFERENCES WARD(WARD_CODE)
);
I am trying to apply a constrain of a Primary Key that has 2 columns in it (HOSP_CODE and WARD_CODE) in table WARD and a Foreign Key constraint that is consisted of the two PK stated above.
Writing this code gives me the error stated in the title.
I have searched quite a lot about this error but couldn't find anything.
I understand that if there is a composite PK then the FK that refers to the same keys needs to be composite.
What I don't understand (and probably is the reason I have the error) is how can I assign the FK that refers to WARD_CODE.
Thank you in advance for your help and excuse me if I am unclear with my question.
P.S. I am new to SQL.
P.S2. The reason I need it this way is because of an assignment that a teacher gave us whose description mentions that table WARD should have a composite PK(HOSP_CODE,WARD_CODE) and two FKs for HOSP_CODE and WARD_CODE.
This is a bit long for a comment.
I think you might want three tables: Hospitals, Wards, and HospitalWards.
What you are calling Ward would be HospitalWards. You need a second table with one row per WardCode. I might think that the tables would look something like this:
CREATE TABLE WARDS (
WARD_CODE INT(3) NOT NULL,
WARD_NAME VARCHAR(20),
);
CREATE TABLE HospitalWards (
HOSP_CODE INT(3) NOT NULL,
WARD_CODE INT(3) NOT NULL,
WARD_NUMBED INT(3),
PRIMARY KEY (HOSP_CODE, WARD_CODE),
FOREIGN KEY (HOSP_CODE) REFERENCES HOSPITALS(HOSP_CODE),
FOREIGN KEY (WARD_CODE) REFERENCES WARDS(WARD_CODE)
);
The number of beds would be in the junction table. Many hospitals might have maternity wards, for instance, but each would have a different number of beds.
Note that I tend to name tables in the plural rather than the singular.

Creating Tables

Suppose you have the following database:
Person(ssn NUMERIC(9), name VARCHAR(40), gender CHAR(1)), ssn is primary key
Organization(org_code CHAR(4), budget INTEGER, org_name VARCHAR(60)), org_code is primary key
Person_Organization(ssn, org_code), both columns are the primary key.
Are the keys in the person_organization table considered foreign keys or primary keys? I am stuck on how to create this table. Have tried looking in my textbooks but cannot find information about it. I don't know if they are supposed to be foreign keys that reference the primary keys or if I should just do this
CREATE TABLE person_organization(ssn NUMERIC(9), org_code VARCHAR(60));
Any suggestions would be greatly appreciated.
Thanks.
The simple answer is that they're both.
ssn, org_code should be the primary key of person_organization.
ssn should be a foreign key back into person and org_code should by a foreign key back into organization.
To separate myself from northpole's answer I don't actually agree with the surrogate key argument in this case it doesn't seem to be needed as it won't be used anywhere else.
Unfortunately the problem with this (good) solution to the many to many relationship is that it's often needed to have two unique keys on a table, ssn, org_code and org_code, ssn and choose one as the primary key.
As you're using Oracle the create table syntax would be
create table person_organization
( ssn number(9)
, org_code varchar2(60)
, constraint person_organization_pk primary key (ssn, org_code)
, constraint person_organization_ssn_fk foreign key ( ssn )
references person ( ssn )
, constraint person_organization_oc_fk foreign key ( org_code )
references organization ( org_code )
);
In your original table creation script you had ssn as numeric(9), which should by number(9). You may want to consider not restricting the size of this data type. You also had org_code as a varchar, this should probably be a varchar2.
Tech on the Net is a really good resource for learning syntax.
I would suggest adding a unique, auto incrementing primary key to PERSON_ORGANIZATION (called something like po_id) as well as the two FOREIGN keys of ssn and org_code. You can also make those two unique if you want. From my experience, I like to have almost every table have it's own unique/auto key (unless it is a lookup table or audit table (and possibly others)).
They're both.
For the person_organization table you would have a compound primary key that consisted of the two columns. Each is separately a foreign key to another table.
For normal database design they should reference the primary keys in the other tables and these constraints enforce the validity of the data in the database.
They are foreign keys.
You've listed "both columns are the primary key" but I don't think they are.
The table does not have a primary key.
The combination of the two fields is certainly acting as a proxy for a primary key, doing things like making sure entries are uniquely identified and thus acting together as a unique identifier but that is a bit different.
I would also recommend adding a separate primary key field for consistency with the structure of others tables. As with other tables I recommend always using either id [my favorite] or tablename_id
This is the basic idea, you need to provide proper datatype for each field
CREATE TABLE Persons (
ssn int(9) NOT NULL PRIMARY KEY,
name varchar(40),
gender CHAR(1)
)
CREATE TABLE Organization (
org_code CHAR(4)NOT NULL PRIMARY KEY,
budget INTEGER,
org_name VARCHAR(60)
)
CREATE TABLE Person_Organization (
ssn int FOREIGN KEY REFERENCES Persons(ssn),
org_code CHAR FOREIGN KEY REFERENCES Organization(org_code)
)