Insert null value in an association table - sql

I have a problem with something in SQL, let's see an example of database :
CREATE TABLE person( //Employee
pe_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
pe_name VARCHAR(20),
pe_office VARCHAR(20)
);
CREATE TABLE project( //Mission
pr_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
pr_name VARCHAR(20),
pr_status VARCHAR(15)
);
CREATE TABLE techno( //Programming language
te_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
te_name VARCHAR(20)
);
CREATE TABLE job( //developer, manager, ...
jo_id PRIMARY KEY NOT NULL AUTO_INCREMENT,
jo_name VARCHAR(20)
);
I would like to assign persons on projects for a job using technos.
For example, Rob works as a developer and project manager on the projet #13 with AngularJS and HTML.
So I created this table :
CREATE TABLE assignment(
pe_id INT,
pr_id INT,
te_id INT,
jo_id INT,
as_days INT, //Days of work
PRIMARY KEY(pe_id, pr_id, tr_id, jo_id),
CONSTRAINT fk_as_pe_id FOREIGN KEY(pe_id) REFERENCES person(pe_id),
CONSTRAINT fk_as_pr_id FOREIGN KEY(pr_id) REFERENCES project(pr_id),
CONSTRAINT fk_as_te_id FOREIGN KEY(te_id) REFERENCES techno(te_id),
CONSTRAINT fk_as_jo_id FOREIGN KEY(jo_id) REFERENCES job(jo_id)
);
I would like to have the ability to assign a developer with somes technos to a project without knowing who exaclty, like this:
INSERT INTO assignment(pr_id,te_id,jo_id,as_days) VALUES(1,2,3,4); //No person!
We suppose that this values exists in project, techno and job tables.
But it seems that I can not insert this, probably because I do not define person's ID (which is in the primary key).
How can I do this ?
Hope I'm understandable :)

You solve this problem by not having this as a primary key. Primary keys cannot be NULL or, if they're composite primary keys, cannot contain NULL. Make it a unique index instead. Create an autonumber field for the primary key. I think this is better solution in your case
Primary Key:
Can be only one in a table
It never allows null values
Primary Key is unique key identifier and can not be null and must be unique.
Unique Key:
Can be more than one unique key in one table.
Unique key can have null values(only single null is allowed).
It can be a candidate key
Unique key can be null and may not be unique.

Maybe you should do this:
Before insert disable constraint:
ALTER INDEX fk_as_pe_id ON assignment
DISABLE;
After insert enable it:
ALTER INDEX fk_as_pe_id ON assignment
REBUILD;

Another alternate way is, if it is possible to alter table structure, just exclude pe_id from the composite primary key in assignment table

Related

Sql creating table consisting of keys from other tables

this is probably a simple question but I am quite new to SQL and databases, so I have been following this site: https://www.postgresqltutorial.com/postgresql-foreign-key/ to try and create a table that consist of primary keys from other tables.
Here I have the structure of the database in an excel overview. With colors showing the relations. i am having problems with the One-To-Many tables. As I get the same error every time "ERROR: column "id" referenced in foreign key constraint does not exist
SQL state: 42703".
The SQL query:
DROP TABLE IF EXISTS ingredient_to_unit_relations;
DROP TABLE IF EXISTS ingrediens;
CREATE TABLE ingrediens (
id serial,
name_of_ingredient varchar(255),
price_per_unit int,
PRIMARY KEY (id)
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id
FOREIGN KEY (id)
REFERENCES ingrediens (id)
);
You need to define the column in order to declare it as a foreign key:
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY,
ingredient_id int,
PRIMARY KEY (ingredient_relation_id),
constraint Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingrediens (id)
);
I might recommend some somewhat different naming conventions (I changed the name id in the table above):
CREATE TABLE ingredients (
ingredient_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name varchar(255),
price_per_unit int
);
CREATE TABLE ingredient_to_unit_relations (
ingredient_relation_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
ingredient_id int,
CONSTRAINT Fk_ingredient_id FOREIGN KEY (ingredient_id) REFERENCES ingredients (ingredient_id)
);
Notes:
I am a fan of naming primary keys after the table they are in. That way, foreign keys and primary keys usually have the same name (and you can use using if you choose).
Avoid SERIAL. GENERATED ALWAYS AS IDENTITY is now recommended.
You can inline primary key constraints (as well as other constraints).
There is not generally a need to repeat the table name in a column (other than the primary key). So, name instead of name_of_ingredient.
Using int for a monetary column is suspicious. It doesn't allow smaller units. That might work for some currencies but in general I would expect a numeric/decimal type.

SQL Constraint names

If we have query for creating table like this..
create table if not exists food
(
id int not null auto_increment,
user_id int,
name varchar(30),
constraint pk_food primary key(id,name),
foreign key(user_id) references userss(id)
);
What does pk_food mean in this example? I know this is a constraint name, but for what we should be give a name for constraint, if its working without?
create table if not exists food
(
id int not null auto_increment,
user_id int,
name varchar(30),
primary key (id, name),
foreign key (user_id) references userss(id)
);
I mean.. how to use these names and for what we need it?
You gives constraints names for basically two reasons:
You can better understand the error message when the constraint is violated.
You can more easily find the constraint if you want to delete it.

No matching unique or primary key for this column-list in Oracle

I have created PERSON table in Oracle by this SQL syntax:
Create table person
(
p_id int not null,
personName char(5) not null );
Then I am trying to create ORDERS table with the following syntax:
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES person(p_id) );
But I am getting the following error .
No matching unique or primary key for this column-list.
What is the problem ? How can I solve this ?
Add primary key to person table:
CREATE TABLE person(
p_id int not null,
personName char(5) not null,
PRIMARY KEY (p_ID)
);
SqlFiddleDemo
Foreign keys enforce a one-to-many relationship. That is, however many records there are in the dependent table they can only reference a single record in the parent table. This means the referenced column(s) in the parent table must be constrained by a PRIMARY or UNIQUE key.
The error message is telling you that there is no such constraint on person(p_id). And lo! if we compare the two DDL statements you have posted we can see that you have created a primary key for ORDERS but not for PERSON.
The solution is simple: constrain P_ID by adding a primary key to PERSON. You can either drop and re-create the table, or you can use an alter table statement to add a primary key.
You should add primary key to person table.
try this:
ALTER TABLE Person
ADD CONSTRAINT p_id PRIMARY KEY (p_id);

Differences between "foreign key" and "constraint foreign key"

I mean for example I can create table like
create table XTable
(
idt int not null primary key,
value nvarchar(50),
idq int,
constraint fk_idq foreign key(idq) references YTable(idq)
)
and I can create it like this
create table XTable
(
idt int not null primary key,
value nvarchar(50),
idq int,
foreign key(idq) references YTable(idq)
)
I usually create table like in the second example but now I'm curious about the first example. What is the difference?
The first one assigns a user-defined name to the foreign key, the second one will assign a system-generated name to the foreign key.
User-defined foreign key names can be useful for subsequent statements like these:
ALTER TABLE XTable DROP CONSTRAINT fk_idq;
ALTER TABLE XTable ENABLE CONSTRAINT fk_idq;
ALTER TABLE XTable DISABLE CONSTRAINT fk_idq;
It's harder to alter constraints with system-generated names, as you have to discover those names first.
The first option is purely for naming the constraint.
From SQL FOREIGN KEY Constraint
To allow naming of a FOREIGN KEY constraint, and for defining a FOREIGN KEY constraint on multiple columns, use the following SQL syntax
CREATE TABLE Orders
(
O_Id int NOT NULL,
OrderNo int NOT NULL,
P_Id int,
PRIMARY KEY (O_Id),
CONSTRAINT fk_PerOrders FOREIGN KEY (P_Id)
REFERENCES Persons(P_Id)
)
Also, from CREATE TABLE (Transact-SQL) one can see that [ CONSTRAINT constraint_name ] is optional.
Apart from controlling the name, nothing really. SQL Server will supply a name if you omit it. FYI, you only need this syntax (SQL Fiddle):
create table XTable
(
idt int not null primary key,
value nvarchar(50),
idq int references YTable(idq)
)
Here's a fuller example.

could unique key ( not primary ) be a parent for declarative foreign key constraint

Naive question with the answer "No" , I believe, but still would like to ask.
Table_parent
pk_parent_surrogate
parent_natural_unique_key
Table_child
pk_child_surrogate
child_natural_NOT_unique
Is that true that the only possible declarative relationship among main database vendors is
pk_parent_surrogate ----------< pk_child_surrogate
and we can't have declarative constraint or foreign key in other words for pair
parent_natural_unique_key -------< child_natural_NOT_unique
My answer here is based on my MS SQL knowledge - although I believe the same answer is correct for ANSI standards as well, i'm not 100% sure...
YES - you CAN do this as long as you've got a unique constraint on the column in your parent table that you want to use as the anchor column for the key.
You can create a FOREIGN KEY constraint as part
of the table definition when you create a table.
If a table already exists, you can add a
FOREIGN KEY constraint, provided that the
FOREIGN KEY constraint is linked to an existing
PRIMARY KEY constraints or UNIQUE constraint in
another, or the same, table. A table can contain
multiple FOREIGN KEY constraints.
And as an example of this sort of key...
use tempdb
CREATE TABLE parent(
pk int identity primary key,
candidate_key int unique not null)
CREATE TABLE child(
pk int identity primary key,
join_key int references parent(candidate_key))
See here for more information.
Try code like this:
create table testunique (id int identity(1,1) primary key, otherid int)
go
create unique index ixOther on testunique(otherid)
go
create table testFK (id int identity(1,1) primary key, someid int)
go
alter table testFK add constraint fkTest foreign key (someid) references testunique(otherid)
Rob