Imagine four tables: A, B, C and D.
Primary key of A table is ID_A.
Primary key of B table is ID_B.
C table has a composite primary key (ID_A,ID_B).
D table references all three other tables and has three foreign keys on two ID_A and ID_B columns. References from D table to B and to C tables are optional.
A B C D
------- ------- ------- -------
ID_A ID_B (ID_A,ID_B)
<--------------------- ID_A
<-------- ID_B
<----------------------------------- ID_A
< - - - - - - - - - - - ID_B
< - - - -(ID_A,ID_B)
I declared mappings for D table as:
mapping.References(e => e.A).Column("ID_A");
mapping.References(e => e.B).Column("ID_B");
mapping.References(e => e.C).Columns("ID_A", "ID_B");
The problem: On attempt to select rows from D table I got ORA-00918: column ambiguously defined because Nhibernate mentioned ID_A and ID_B columns two times in generated SQL query.
Question: How should I specify mappings for D table?
In such situation, I just map C in D, A and B being mapped in C, thus you can navigate from D to A or B through C.
In my experience, trying to shortcut in such a situation was not having any strong benefit, and was causing too much issues (not worth the trouble). (Maybe I have not even ever achieved an actually functional "shortcut".)
Related
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.
I have to answer this question about UNIQUE statements. In particolar, the question ask me to indicate which is the maximum number of unique statements someone can define on a relation of 5 columns. I suppose that this number should be 5^5. Is this right?
And another question about Foreign Keys ask me whether attribute A for a relation R can be Foreign Key referencing B in relation S, even if A is not primary key for R. I think that because a FK constraint can also include NULL values, an attribute specified as FK referencing a PK on another table shouldn't be a primary key itself. Is it right?
Thank you in advance!
The maximum number of distinct unique relationships you can define is 2^n - 1. Basically, any given column can be in or out of the relationship. The "- 1" is because you cannot define a unique relationship with no columns.
For instance, with three columns, you can have:
A
B
C
A, B
A, C
B, C
A, B, C
If you think of these as binary numbers, you will see the pattern:
100
010
001
110
101
011
111
I have two tables, data/model is fake for simplicity purposes:
Table A:
Order ID Delivered
1 Y
2 N
3 Y
And
Table B:
Order ID Customer ID
1 123
1 234
1 455
2 789
Order ID is a primary key on Table A, and I want to use it as a Foreign Key on Table B.
Is this acceptable, given that Order ID on Table B is not unique?
Please ignore any normalisation/structural issues, my question is simply whether you can have a non-unique foreign key, I just thought the illustration would help..
Thanks,
Dearg
Is this acceptable, given that Order ID on Table B is not unique?
Yes, absolutely. This is the standard way of modeling a 1:many relationship
You should nevertheless find a primary key for TableB. If a customer cannot be assigned to more than one order, then using (order_id, customer_id) as the PK would make sense.
I've seen questions similar to mine, but none exactly the same.
Suppose, I have the following (simplified) tables:
Table A
aID int PRIMARY KEY
10
11
Table B
bID int PRIMARY KEY, aID int FOREIGN KEY referencing A.aID
100, 10
101, 11
Table C
cID int PRIMARY KEY, bID int FOREIGN KEY referencing B.bID
1001, 101
Table D
aID int, bID int, cID int
11, 101, 1001
I want Table D to be constrained so that:
aID, bID, cID are all valid ID values
aID and bID are a valid pair from Table B
bID and cID are a valid pair from Table C
Number 1. is easy to take care of with Foreign key constraints.
But suppose I update table C to instead be
1001, 100
How can I make sure table D is automatically updated to be
10, 100, 1001
Notice that 2 fields have to change here in order to satisfy 2. and 3. above. Is there a way to do this with Foreign keys, or is an AFTER UPDATE trigger the only way?
According to my point in this type of case don't create other table D with select all the data based on inner join of table (A-B)-C in your case y create table D by sql select statement but define one extra trigger for update on B,C so they can truncate the table D so D is reconstruct again
I ended up changing Table D to be a VIEW that is a JOIN of Tables B and C.
CREATE VIEW D AS
SELECT BB.aID, BB.bID, CC.cID FROM B BB
JOIN C CC
ON CC.bID = BB.bID
Once I realized doing this gave me what I wanted, it became much, much simpler to manage.
I have a Winforms application which uses a database.
Now in the database I have these tables:
table A (PK = Identity - auto increment)
table B (PK = Identity - auto increment)
table C (FK = table A's PK and table B's PK)
Tables A and B are strangers so I added the table C to connect them.
I'm trying to do a cascading delete, so when I'm deleting a row from table A, it will delete the related rows from tables B and C.
I set the relation between tables A and C and B and C.
But when I'm deleting one row from table A it deletes from table C but not from B.
why?
I can't set table C to be the parent of table B because the primary key...
I suggest you to add specific treatment to delete your data when you wish cascade treatment. best practise, in order to control your deleting system.