Insert multiple values into the same row for a single foreign key - sql

I'm creating a project for a hotel reservation, and I want to insert multiple values into a column which is a foreign key in a table that has a primary key column but it's not possible to insert a duplicate key when it's primary and it's not possible to insert different values than the values that inserted in the main column that I used it as foreign key in this table, so what can I do?
Clarification
I have a table for reservation and another table for hotel services, there is a column in [Reservation] table which is the primary key (ReservationID) and there is a column in the [Hotel_Services] table that I used as a foreign key to the [Reservation] table which is (ServiceID).
What I want is to insert multiple service IDs into each reservation to indicates the services that each guest has added to his reservation, how can I do this?
Table #1: Reservation
`ReservationID` (primary key) e.g 10,20,30
Table #2: Hotel_Services
`ServiceID` (foreign key to `Reservations`) e.g 1, 2, 3
Desired result: add multiple service IDs into each reservation
e.g:
Reservation 10 has 1,2 services
Reservation 20 has 1,3 services
Reservation 30 has 2,3 services

You need a table ReservationServices, defined something like this:
create table ReservationServices (
ReservationServiceId int identity primary key,
ReservationId int not null references reservations(reservationid),
ServiceId int not null references services(serviceid);
);
Then your data would look like:
ReservationServiceId ReservationId ServiceId
1 10 1
2 10 2
3 20 1
4 20 3
. . .
So, inserting a new service for a reservation is, well, as simple as inserting a new row in this table.

Related

Violation of primarary key

I am trying to create a many-to-many relationship between two tables Asset and Inventory, I created an intermediate table called Asset_Inventory
One or more assets can be in an inventory, and an inventory can be in one or more assets,but it does not allow me to insert data
Mistake
The data in row 2 was not committed. Error source Message: Violation of PRIMARY KEY CONSTRAINT
PK_INVENTORY_ASSET. Cannot insert duplicate key in object dbo.Inventory_Asset. The duplicate key value (1,1).
-- TABLE INVENTORY
GO
CREATE TABLE Inventory
(
[inventory_id] INT NOT NULL IDENTITY(1,1),
[company_id] INT,
[name] VARCHAR(50),
[observations] VARCHAR(500),
[date_created] DATETIME DEFAULT(GETDATE()),
CONSTRAINT PK_INVENTORY PRIMARY KEY (inventory_id),
CONSTRAINT FK_INVENTORY_COMPANY FOREIGN KEY(company_id) REFERENCES Company(company_id)
)
-- TABLE ASSET
GO
CREATE TABLE Asset
(
[asset_id] INT NOT NULL IDENTITY(1,1),
[company_id] INT,
[code] INT,
[model_name] VARCHAR(50),
[model_number] VARCHAR(50),
[serial_number] VARCHAR(30),
[price] DECIMAL(10,2),
CONSTRAINT PK_ASSET_ID PRIMARY KEY(asset_id),
CONSTRAINT FK_ASSET_COMPANY FOREIGN KEY(company_id) REFERENCES Company(company_id),
CONSTRAINT UQ_ASSET_CODE UNIQUE(code)
)
--TABLE INVENTORY_ASSET
CREATE TABLE Inventory_Asset
(
asset_id INT,
inventory_id INT,
CONSTRAINT PK_INVENTORY_ASSET PRIMARY KEY (asset_id,inventory_id),
CONSTRAINT FK_ASSET_ID FOREIGN KEY (asset_id) REFERENCES Asset(asset_id),
CONSTRAINT FK_IVENTORY_ID FOREIGN KEY (inventory_id) REFERENCES Inventory(inventory_id)
)
UPDATED
it's hard for me to ask this question
N companies have many assets; you need to have control over them. Have a list of assets by company, to which employee it was assigned, or in which department of the company that asset is located. a total of assets by company etc..
What is the purpose of this?
I need to physically label (bar code) each asset with a unique code
Cell phones, monitors, keyboards, servers, PCs, laptops, chairs, furniture, etc...
Once all the assets have been tagged in the
company 1
company 2
company 3
I have to scan each code printed on the asset and make a monthly cut
I have to create a report with this information
In the company 1 an inventory was made in the month of January
Cut of the month of January:
20 monitors (10 dell , 10hp)
20 chairs
10 computers
the next month this cut is made again to see if there is the same quantity, if the 2 inventories of the month of January and February are not the same, some asset was stolen and to be able to identify this
an inventory can have one or more assets, and an asset can be in one or more inventories.
I think I can do this with the Inventory_Asset table
asset_id
iventory_id
1
1
1
1
2
1
3
1
1
1
1
2
2
2
1
2
6
2
1
3
4
3
3
3
1
3
Am I wrong with my solution?
--TABLE INVENTORY_ASSET
CREATE TABLE Inventory_Asset
(
[inventory_id] INT,
[asset_id] INT,
CONSTRAINT FK_ASSET_ID FOREIGN KEY (asset_id) REFERENCES Asset(asset_id),
CONSTRAINT FK_IVENTORY_ID FOREIGN KEY (inventory_id) REFERENCES Inventory(inventory_id)
)
CONSTRAINT PK_INVENTORY_ASSET PRIMARY KEY (asset_id,inventory_id),
PRIMARY KEYS must be unique. That is why you can't add this -- since it conflicts with your primary key. If you don't want that to be unique but you do expect to use it as an index you can make an index that does not enforce uniqueness and make something else your primary key.
The answers and comments here are all correct; but perhaps we need to review what a many-to-many relation can be used for.
Option 1: we just need a link between two entities
This is what you have done. Basically it will serve if you want to know in which Inventories a given Asset is, which Assets a given Inventory holds, etc. In this scenario when you have established the link once (Asset 1 is in Inventory 1) there's no reason to re-establish it with further records.
Option 2: we want to store some information about the relation
This is what I suspect you really wanted. Suppose for instance you want to store how many Assets of type 1 are in Inventory 1. In this case what you want is to add a "Quantity" column to your Inventory_asset table. Once more, if there are 3 Assets of type 1 in Inventory 1 you won't duplicate the records: you will just create one record and put 3 in the new column.
Option 3: we really need multiple records
Suppose you want to store not only how many Assets of a given type are in a given Inventory, but also on which date a few of them were put there. So you may have 2 type 1 Assets put in Inventory 1 on May, 1st, and other 3 of them on May, 15th. In this case the date must become part of the PK, so that the system (and you too!) can distinguish between the different records. You may also decide to create an auto-increment column and use it as a PK instead; but note that while it may be simpler to handle, it would allow for unvoluntarily creating duplicate records, so I wouldn't recommend it.

Foreign key without correspondence in the referenced table

I'm trying to come up with a solution for an exercise in which I have to create 3 tables: one for employees, one for projects, and one for projects and employees, in which I have to insert the employee's ID and associate with a project ID. In the project_employee table, since it has only 2 columns that reference other tables, I thought I could set them bot as foreign keys, like this:
CREATE TABLE employee_project
(
id_employee numeric FOREIGN KEY REFERENCES employee(id_employee),
id_project numeric FOREIGN KEY REFERENCES project(id_project)
)
Then I stumbled upon a problem: when inserting values on the 3 tables, I noticed that one of the employee's ID number was 4, but on the table employee there was no line with ID 4. Of course, this line wasn't created, but I want to understand: is there a way I could create a line whose ID has no matching record in the referenced table? Could it be a possible mistake in the question, or is there something I'm missing? Thanks in advance for your time!
If there is no rows in employee table with id_employee value 4 then there should not be rows in employee_project table with id_employee value 4. SQL Server will give you an error like below:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__employee__id__75F77EB0". The conflict occurred in database "test", table "dbo.employee", column 'id_employee'.
But if you want to create employee_project with composite primary key on both the column you can try this:
CREATE TABLE employee_project
(
id_employee int not null,
id_project int not null,
primary key(id_employee, id_project )
)

Allowing only unique combination in sql table

I'm trying to create a sql table in net frame work in VS that has room and user id ,but I want that only one of each combination can exist in the table:
Want:
room --- user id
1 2
1 3
3 2
2 1
1 1
3 1
Dont want:
room --- user id
1 2
1 2
how can I make it so that only unique combination can be entered?
You can enforce uniqueness using a unique constraint or index:
create unique index unq_t_room_userid on t(room, user_id);
or:
alter table t add constraint unq_t_room_userid
unique (room, user_id);
Looks like you want Room, UserId to be the PRIMARY KEY on that table.
CREATE TABLE Occupancy
(
RoomId INT NOT NULL
,UserId INT NOT NULL
,CONSTRAINT PK_Occupancy PRIMARY KEY CLUSTERED (RoomId,UserId)
)
When you try to insert a duplicate value:
INSERT dbo.Occupancy (RoomId,UserId)
VALUES
(1,1)
,(1,2)
,(1,1)
GO
You will get a message like this:
Violation of PRIMARY KEY constraint 'PK_Occupancy'. Cannot insert
duplicate key in object 'dbo.Occupancy'. The duplicate key value is
(1, 1).

Storing multiple values in a single column

I have two columns in my table: [Employee_id, Employee_phno].
Employee_id: primary key, data type = int
Employee_phno: allows null, data type = int
Now, how can I insert two phone numbers in the same employee_id?
For example:
employee_id employee_phno()
1 xxxxxxxxx
yyyyyyyyyy
For me, if you want multiple data for column Employee_phno better make another table for Employee_phno. In your second table, set a foreign key as relation for your first table.
Example:
1st table
Employee_id
1
2
3
2nd table
Employee_id Employee_phno
1 1234
2 1512
2 4523
Here you can see the employee with id = 2 has multiple Employee_phno
It is never possible to insert data in such way in single table.
If Employee_id is primary key then you can have only 1 record for an employee.Since you have only one field for Employee_phno,it's not possible to store 2 phone numbers for the same employee.
For doing so, you will have to do any one of the following:
1.Add another column in the data as Employee_Alternate_phno and if all the employees won't have 2 numbers you can make this column allow NULLs.
2.Create another mapping table say EmployeeNumbers where you will have EmployeeId as Foreign key and then the numbers field. Anytime if you want the 2 Employee_phno you can do a join on the mapping table and retrieve the values.

How to reference foreign key from more than one column (Inconsistent values)

I Have table three tables:
The first one is emps:
create table emps (id number primary key , name nvarchar2(20));
The second one is cars:
create table cars (id number primary key , car_name varchar2(20));
The third one is accounts:
create table accounts (acc_id number primary key, woner_table nvarchar2(20) ,
woner_id number references emps(id) references cars(id));
Now I Have these values for selected tables:
Emps:
ID Name
-------------------
1 Ali
2 Ahmed
Cars:
ID Name
------------------------
107 Camery 2016
108 Ford 2012
I Want to
Insert values in accounts table so its data should be like this:
Accounts:
Acc_no Woner_Table Woner_ID
------------------------------------------
11013 EMPS 1
12010 CARS 107
I tried to perform this SQL statement:
Insert into accounts (acc_id , woner_table , woner_id) values (11013,'EMPS',1);
BUT I get this error:
ERROR at line 1:
ORA-02291: integrity constraint (HR.SYS_C0016548) violated - parent key not found.
This error occurs because the value of woner_id column doesn't exist in cars table.
My work require link tables in this way.
How Can I Solve This Problem Please ?!..
Mean: How can I reference tables in previous way and Insert values without this problem ?..
One-of relationships are tricky in SQL. With your data structure here is one possibility:
create table accounts (
acc_id number primary key,
emp_id number references emps(id),
car_id number references car(id),
id as (coalesce(emp_id, car_id)),
woner_table as (case when emp_id is not null then 'Emps'
when car_id is not null then 'Cars'
end),
constraint chk_accounts_car_emp check (emp_id is null or car_id is null)
);
You can fetch the id in a select. However, for the insert, you need to be explicit:
Insert into accounts (acc_id , emp_id)
values (11013, 1);
Note: Earlier versions of Oracle do not support virtual columns, but you can do almost the same thing using a view.
Your approach should be changed such that your Account table contains two foreign key fields - one for each foreign table. Like this:
create table accounts (acc_id number primary key,
empsId number references emps(id),
carsId number references cars(id));
The easiest, most straightforward method to do this is as STLDeveloper says, add additional FK columns, one for each table. This also bring along with it the benefit of the database being able to enforce Referential Integrity.
BUT, if you choose not to do, then the next option is to use one FK column for the the FK values and a second column to indicate what table the value refers to. This keeps the number of columns small = 2 max, regardless of number of tables with FKs. But, this significantly increases the programming burden for the application logic and/or PL/SQL, SQL. And, of course, you completely lose Database enforcement of RI.