How to setup table A in such way, that a only one row from table B with a certain value can have foreign key relation to a row from table A? - sql

We have table A. Table B has foreign key to A. And now, if there is already a row in table B with attribute surname="Jordan" that has foreign key relation to a particular row in A , it will be impossible to create another row in table B with the same surname that will have relation with the same row in A.
How to solve this problem.

Create a unique index on Table B's foreign key column.
Note that this suggests Table B should probably be folded into Table A.

Related

DELETE request on row with nested foreign keys

I have a Table A that is referenced to by Table B, and Table C has references to Table B.
Such that:
Table A (pk: id)
Table B (pk: id, fk: A_id)
Table C (fk: B_id)
Every foreign key has a constraint ON_DELETE:CASCADE, however if I attempted to delete Table A - it refuses to. This is happening because rows in Table B have foreign keys pointing to Table A, and Table C has rows pointing to Table B.
I'm confident that I can resolve this issue by deleting Table B first, and then deleting Table A. However, would someone explain why this DELETE isn't possible? Surely, it should be able to perform a function of going down a 'hierarchy' of foreign keys and deleting everything in order?
Thanks
In ON DELETE CASCADE operation, if a parent row is deleted, it will first delete the child row and then the parent row so as to ensure that no references are left as foreign key
As for your question, since Table B is referring to Table A 's primary key and Table C is referring to Table B's primary key, the relationship for which on delete cascade should work is just a parent child and not beyond.

How to create SQL constraint on primary key to make sure it could only be referenced once?

How do I add constraint to guard that a primary key could only be referenced once?(It could be referenced in two tables)
Each reference should have a unique value out of the primary key.
Table A
----------------------
id
1
2
3
4
Table B
----------------------
id a_id (foreign key to table A.id)
1 2
2 3
Table C
----------------------
id a_id (foreign key to table A.id)
1 1
I want something to happen to give error when try to insert a_id = 2 into table C as its used in table B already.
You can use an INSERT, UPDATE trigger on each of the child tables to ensure that the PK of the parent table that is about to be inserted or updated does not already exist in the other child table.
What you are trying to do requires another table D, that will help unify the references to A.
Table D will contain its own primary key ( Id ), a reference to table A with a UNIQUE constraint on it (call it AId ), and a third column (called "RowType") to indicate to which of the child tables (B or C) the row corresponds. You can make this column to be of type int, and assign value "0" for B and "1" for C, for example.
Then in table B you add a foreign key to D.Id, AND another column "BRowType" as foreign key to D.RowType; then you define a constraint on this column, so it can only have the value '0' ( or whatever value you have decided to correspond to this table).
For table C your constraint will limit the values to '1'.
Or course, in order to insert a record into B or C you first need to create a record in D. But once you have a record in B that references a record in D, which in turn links to a record in A, you will no longer be able to create a record in C for the same line in A - because of the UNIQUE constraint on D.AId AND the constraint on C.BRowType.
If I understand the question correctly, it sounds like you need to add a unique constraint on the column of each table that references your primary key.
For example:
Table A
----------------------
id (primary key)
1
2
3
Table B
----------------------
id a_id (foreign key to table A.id)
1 2
2 3
Set the a_id column to be UNIQUE and that way you can ensure that the primary key from Table A is not used twice. You would do that in each table which references A.id
If you want to avoid using triggers, you could create a table X with id and a unique constraint on it.
In each transaction in which you insert a record into B or C you have to insert into X as well. Both insertions will only be possible if not yet in the other table.

composite primary key in which 1 key is from different table with different database

I have 2 different tables in two different databases.
lets say,
In DB1, I have table "A" with columns as "C1" as primary key, "C2", "C3".
In DB2, I have table "B" with columns as "X1", "X2", "X3".
Now, I want to make a composite primary key in table B, such that fields are ("C1", "X1") as Composite_PK1, "X2", "X3".
Can anyone explain how to use other table's primary key as one of the elements of the composite primary key in another table?
A table's primary key must be made from a column or columns in the table itself, so your question doesn't really make sense.
If you have this table in the database called DB_ONE
A
C1 PK
C2
C3
and this table in the database called DB_TWO
B
C1 FK to column C1 in Table DB_ONE.A
X1
X2
you can define the primary key of table B as (C1, X1) if you wish. But the column C1 must be in table B. A particular column in any table can serve as both a foreign key (FK) and all or part of a primary key (PK).
If your tables are in different database schemas on the same Oracle instance you can try to use the schema-qualified table name (DB_ONE.A) when creating a foreign key. DDL like this might do the trick for you.
ALTER TABLE DB_TWO.B
ADD CONSTRAINT fk_my_favorite_name
FOREIGN KEY (C1)
REFERENCES DB_ONE.A (C1);
If they are on different Oracle instances, you are out of luck trying to set up a foreign key.

How can I use a look-up table for the column names of a table in sqlite3?

I have a table for example
I need to create a lookup table that references the column names of this table. (Column names are unique) Eg. SNo is SerialNumberOfChinaAsia etc and I want to store this new name as a primary key in another table and refer the old name SNo as a foreign key using SQlite3. How can such a lookup table be created?
Originally I have a table with 300 columns and the big column names do not fit in the query during table creation.

Both sides of a many to many relationship also relate to the same 3rd party

In a relational database. Two tables can be related in a many to many fashion with a mapping table that has foreign keys to the other two tables primary keys, while both still being related to another table.
For example.
Table A
AId -PK
CId -FK
Table B
BId -PK
CId -FK
Mapping Table m
AId -FK
BId -FK
(composite PK of the above)
Table C
CId -PK
How would I modify this so both the tables in the many to many relationship setup in such a way that a row from Table A and a row from Table B can only be related to each other through mapping table m if the row in A and B are also related to the same row in Table C?
1. Make TableA.CId and TableB.CId both FKs to Table C.ID.
2. Add a unique index in TableA on columns AId and CId.
3. Add a unique index in TableB on columns BId and CId.
4. Add a CId column to TableM.
5. Then Add two FKs in Table M,
a. One using columns (AId, CId) pointing to Unique composite Index in Table A, and
b. the other using columns (BId, CId) pointing to Unique composite Index in Table B.