Oracle - Cannot create new FK on existing table - sql

I'm convinced I must be doing something incredibly stupid, as it can't be this hard to add a new foreign key to an existing table. However, I'm still stuck. Here's what I'm doing.
First, I created a new column in TPM_USER to store which team a user is on:
ALTER TABLE TPM_USER ADD (
"TEAMID" NUMBER NULL
)
This works without errors, and I can query the TPM_USER table to see the new column has been added. Next, I want TEAMID to refer to a row in the already existing TPM_DEVELOPMENTTEAMS table. So I do:
ALTER TABLE TPM_USER
ADD CONSTRAINT TPM_USER_FK1
FOREIGN KEY(TEAMID)
REFERENCES TPM_DEVELOPMENTTEAMS(TEAMID)
This gives me the error:
ORA-02270: no matching unique or primary key for this column-list
I've checked both TEAMID columns are the same data type (NUMBER) and TEAMID is of course the primary key of the DEVELOPMENTTEAMS table. In fact, here's the schema for DEVELOPMENTTEAMS:
CREATE TABLE TPMDBO.TPM_DEVELOPMENTTEAMS (
TEAMID NUMBER NULL,
NAME VARCHAR2(100) NOT NULL,
ISACTIVE CHAR(1) NULL,
SORTORDER NUMBER NULL,
SHORTNAME VARCHAR2(100) NULL,
GROUPID NUMBER NOT NULL,
CONSTRAINT TPM_DEVELOPMENTTEAMS_PK PRIMARY KEY(TEAMID)
NOT DEFERRABLE
DISABLE NOVALIDATE
)
I even tried the GUI interface in Aqua Data Studio to add the new constraint as well, so I'm sure I didn't misspell anything. What am I doing wrong?

Your PK is disabled. Enable it with:
ALTER TABLE TPM_DEVELOPMENTTEAMS ENABLE CONSTRAINT TPM_DEVELOPMENTTEAMS_PK;
BTW, by declaring it PK, you also made TPM_DEVELOPMENTTEAMS.TEAMID non-NULL (so there is no purpose for NULL after it).

You can only refer the column(or combination of columns) which are either enabled Primary Key or Unique Key for the same/other table.
If you find your constraint disabled in below query then you cant create Foreign Key for that PK/UK. You should enable it.
select constraint_name from dba_constraints
where constraint_type in ('P','U')
and status = 'DISABLED'
and lower(table_name) = lower(:p_table_name);

Related

Why PSQL create table returns [42P01] ERROR: relation does not exist

I'm new to SQL. I was trying to run sql schema, here is a part of code
create table PageColours (
id serial,
userID serial references users(id),
--references users(id),
isTemplate boolean default'false',
name NameValue not null unique,
primary key (id)
);
create table People (
id serial,
email EmailValue not null unique,
givenName NameValue not null,
familyName NameValue,
invitedID serial references Events(id),
attendedID serial references Events(id),
primary key (id)
);
create table users(
id serial
references People(id),
passWord varchar not null,
BillingAddress serial not null
references Places(id),
HomeAddress serial
references Places(id),
ListID serial
references ContactLists(id),
ColorID serial
references PageColours(id),
primary key (id)
);
It returns[2020-07-03 15:28:19] [42P01] ERROR: relation "people" does not exist
[2020-07-03 15:28:19] [42P01] ERROR: relation "users" does not exist
In fact all foreign key reference table reference not exist. When i remove the reference, the table can be created, can someone please help me ?
The script is run sequentially. So when the pagecolours table is created, the users table does not yet exist and thus the references users fails.
You need to re-order the script, so that the users table is created first. But as you have a circular reference (users references pagecolours and pagecolours references users) you need to create the tables without an "inline" reference, and then at the end of the script you need to run an ALTER TABLE to create the foreign keys.
But having a circular reference like that, is usually not a good idea. But if you are 100% sure you need it, you should at least declare the foreign keys as deferrable, to make inserting rows easier.
Also: serial is not a datatype. A foreign key column that references a serial column should be defined as an integer. In general it is recommended to move away from serial and use integer generated always as identity instead.

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.

Difference between using or not using CONSTRAINT keyword on SQL Server

What is the difference between using or not using the CONSTRAINT keyword when working with Foreign Keys on SQL Server?
I noticed that apparently both worked the same in this specific case, without CONSTRAINT:
CREATE TABLE ClientsPhones
(
ClientPhone varchar(10) NOT NULL,
ClientID smallint NOT NULL,
PRIMARY KEY (ClientPhone),
FOREIGN KEY (ClientID) REFERENCES Clients(ClientID)
);
And with CONSTRAINT:
CREATE TABLE ClientsPhones
(
ClientPhone varchar(10) NOT NULL,
ClientID smallint NOT NULL,
PRIMARY KEY (ClientPhone),
CONSTRAINT fk_ClientID
FOREIGN KEY (ClientID) REFERENCES Clients(ClientID)
);
Both didn't let me add records to the table unless the ClientID already existed on the Clients table, and the same ClientID and ClientPhone weren't already on the ClientsPhones table.
Is there any real difference between the two besides the fact that I'm able to name the constraint?
If you don't create constraint.it will automatically create own constraint name
the foreign key index name is generated using the name of the referencing foreign key column Automatically.
So there is no way to see difference of using and not using Constraint keyword. by default constraint name will be defined.
I did some research and don't believe Hell Boy's answer was as clear as it could be and had some misinformation.
Every constraint you add to a database has a name set by default. This includes PRIMARY KEY, FOREIGN KEY, DEFAULT, NOT NULL. It isn't necessarily the name of the column(s) used.
You can imagine that when you don't use the CONSTRAINT keyword SQL Server puts it there as well as generates a name for you.
If you want to remove or change a constrain you would either have to delete the entire table and recreate it with the correct constraints or you can reference the constraint by name and then alter it somewhat like a column using the ALTER keyword. This can be useful for when you need to delete a table with a foreign key. If you name the foreign key constraint you can delete it and then the table instead of having to delete the table the foreign key points to.

create foreign key in oracle

is there anyone who can help me to create a foreign key for my Status table. I need to PLACE a foreign key constraint on the code in the status table, referring to the id in the Building table.
TABLE building
(
build_name VARCHAR2(50,0) NOT NULL,
id NUMBER (38,0) NOT NULL,
mapid NUMBER (10,0) NOT NULL
);
TABLE STATUS
(
code VARCHAR(2 BYTE) NOT NULL,
status_name VARCHAR2(40 BYTE) NOT NULL,
);
Bulding table has constraint building_gmidx with id as primary key.
Here is a quick syntax for your current requirement, however I recommend you to go through the oracle documentation for a proper understanding of what this means.
ALTER TABLE STATUS ADD (
CONSTRAINT status_fk_building FOREIGN KEY (code)
REFERENCES building (id)
ENABLE VALIDATE);
Did you leave out CREATE TABLE *name* to save time when writing the question? The first thing I see is that your Foreign key has to have the same data type and size as your Primary key. If the Tables already exist the code would be:
ALTER TABLE status MODIFY (code NUMBER(38));
From there you would need to
ALTER TABLE status ADD FOREIGN KEY (code) REFERENCES (building_gmidx)
Why is the constraint for building Primary key named building_gmidx and the column plain id?? All Normalized table attributes should be Unique. Wouldn't it be better if you just named the column "id" building_gmidx instead. Just in case there are other types of id's added later you do not have to think about which table "id" pertains to. Let me know if this works.

Trouble understanding SQL (Oracle) create table code

I am aware of Oracle's create table syntax
CREATE TABLE MyTable(
id int primary key,
...
);
This will create a table called MyTable with an int primary key. So, nothing new here.
but I am having difficulties understanding the following query:
CREATE TABLE departament (
cod_dept INTEGER CONSTRAINT dept_key PRIMARY KEY,
dept_name CHAR(15) NOT NULL,
admission DATE NOT NULL,
localization CHAR(20))
When I look up on Oracle's SQL Developer software on departement's table, I can see 4 columns: cod_dept, dept_name, admission and localization. On the constraints tab, I can also see dept_key, but I am confused as to what this might mean. What is dept_key purpose here?
Edit
Ok, seems it is a way to define the name of the constraint you're adding to the table. My next question is why don't you just call it the same name as the primary key column? From what I've seen it seems Oracle by default just creates a random name for the constraint!
Thanks
When you write id int primary key, Oracle will create a primary key constraint to ensure uniqueness of primary key values. All constraints have names, so in this case Oracle assigns an autogenerated name to this constraint. But you can set a name of this constraint explicitly using the CONSTRAINT syntax:
cod_dept INTEGER CONSTRAINT dept_key PRIMARY KEY
This name may be used later to refer to the constraint, for example, to delete or modify it:
ALTER TABLE department DROP CONSTRAINT dept_key;
EDIT:
Constraint names are unique across the schema, so Oracle can't just use the name of primary key column as a constraint name.
Primary keys can be explicitly be named. dept_key is just a name.
dept_key is the name of the primary key constraint. That means cod_dept is the unique identifier for your table, the mechanism for identifying a row, and so it can only have one occurrence of any given value.
That is the constraint you created representing the primary key.
A table is made up of:
Columns (where the data lives)
Indexes (indexed copies of the data used for faster searching)
Constraints (rules about what data can be in the table, including PK, FK, and check constraints).
dept_key is the name of the constraint. You specified the name here : "INTEGER CONSTRAINT dept_key PRIMARY KEY," so it will create a constraint with the name dept_key.
Another syntax for the same would be to write the following after your CREATE TABLE instruction.
ALTER TABLE department
ADD CONSTRAINT dept_key PRIMARY KEY (cod_dept)
dept_key is then the name of the constraint you created to be the primary key for this table. In order for a database engine to know the primary key, and to index it for fastest results and so forth, it needs to create a known constraint that is indexed. Here, it is you who has given the name which is dept_key.
For you kind information, it is often seen to write PK_[table name] for primary keys constraints and FK_[current_table_name]_[foreign_table_name] for foreign keys constraints.
Hope this helps! =)
I think whenever we create a Primary Key value then by default Oracle will crate constraint for it with the same name but it looks like that u are creating constraint with some other name.
Thank You