I am trying to set a foreign key between two tables with the following structure:
Table 1
Contract
Beginning
End
V001
01.01.20
01.01.21
V001
02.01.21
31.12.22
and
Table 2
Contract
Date
V001
15.05.20
V002
10.02.21
How can I set a foreign key such that it maps the rows where the date is between the beginning and the end date?
I've tried to add a where clause after the foreign key constraint but that did not work.
Related
I'm trying to get the following scenario to work:
I have three tables, and one of them (IncidentDetail) is to hold incident information of the other two (Incident and PendIncident). I want the IncidentDetail table to reference either an incident in the Incident, or PendIncident table so it could exist in either place. How would I set up the constraints?
Table 1 - Incident:
+--------------------+
| IncidentNbr | Desc |
+--------------------+
Table 2 - PendIncident:
+------------------------+
| PendIncidentNbr | Desc |
+------------------------+
Table 3 - IncidentDetail:
+-----------------------+
| IncidentNbr | Details |
+-----------------------+
The IncidentDetail table will have a FK constraint so that the IncidentDetail.IncidentNbr will need to have a value in either the Incident.IncidentNbr column OR the PendIncident.PendIncidentNbr column.
Is it possible to have a FK constraint on a single column that references into two different tables or will I need a second PendIncidentNbr column in the IncidentDetail table that has its own FK constraint to PendIncident.PendIncidentNbr?
Is that enough to ensure that the IncidentDetail table satisfies at least one of the FK constraints?
The other approach I can think of is to drop the FK constraints all together and use a check constraint where either the IncidentDetail.IncidentNbr column or IncidentDetail.PendIncidentNbr column has a value.
You can have FK constraints on a single column that references into two different tables but it will not work with your use case.
Since an incidentNbr exists either in Incident table or PendIncident table at any given point in time, having two FK constraints in IncidentDetail table will fail as soon as you attempt to insert a record in this child table. Since the incident exists in one parent table but not the other, it will throw an integrity constraint violation error w.r.t. second FK.
Using a check constraint can be a viable solution for this scenario.
Code snippet for quick reference -
Create table table_a(col_a number primary key);
Create table table_b(col_b number primary key);
Create table table_c(col_c number);
ALTER TABLE table_c
ADD CONSTRAINT fk_c_a
FOREIGN KEY (col_c)
REFERENCES table_a(col_a);
ALTER TABLE table_c
ADD CONSTRAINT fk_c_b
FOREIGN KEY (col_c)
REFERENCES table_b(col_b);
Insert into table_a values(100);
Insert into table_b values(200);
Insert into table_c values(100); —-This statement will throw integrity constraint violation error
No, a foreign key can only refer to one parent table.
You will either need two separate columns in INCIDENT_DETAIL, each with its own FK, or else combine INCIDENT and PENDINCIDENT into a single table with a type or status column.
The fact that you find yourself with a single column that seems to refer to either of two parent tables suggests to me that perhaps they are really the same thing at different states of processing.
I have a table that I need to insert data into.
The table Sales has 4 columns
CustomerValueType_id (int)
Customer_id (int)
Value (NVARCHAR)
Customer_name (NVARCHAR)
The CustomerValueType_id, Customer_id are foreign keys that are not-unique, CustomerValueType_id matches to a value type, while Customer_id matches to the Customer_name.
I need to add additional customer data into the Valuecolumn but how do I ensure that the data matches to the correct CustomerValueType_id and Customer_id and each customer name has to be repeated in the Customer_name
Sales Table
You are trying to do denormalization.
Ideally, in the normalized design, you will just store, parent_ids in
the child table. If you want to see parent_name fields, you have to
get them based on JOIN conditions.
But, here as you are storing both id, name in the child table, I would suggest you to create composite Foreign key in the child table, so that the combination is always present. Also, make this combination as composite primary key in the parent table.
-- Parent Table PRIMARY KEY
ALTER TABLE dbo.CustomerValueType
ADD CONSTRAINT PK_CustomerValueType
PRIMARY KEY CLUSTERED (CustomerValueType_id, Value);
GO
--Child Table FOREIGN KEY
ALTER TABLE dbo.Sales
ADD CONSTRAINT FK_Sales_CustomerValueType
FOREIGN KEY (CustomerValueType_id,Value)
REFERENCES dbo.CustomerValueType(CustomerValueType_id,Value);
GO
Let's say I have two tables: Entries and Entry_Locks.
Entries has 3 columns:
Entry_ID (Primary key),
Entry_Data,
Entry_Lock_ID (foreign key to Entry_Locks table - references Column Entry_Lock_ID).
Entry_Locks has 3 columns:
Entry_ID (foreign key to Entries table - references Column Entry_ID),
Entry_Lock_ID (primary key),
Timestamp.
Now I insert a row into Entry_Locks with an Entry_ID = 50 and Entry_Lock_ID = 25. I would like the row in Entries with Entry_ID = 50 to automatically have the column Entry_Lock_ID updated with the value 25, to reference the correct Entry_Lock_ID.
Right now my Entry_Locks schema looks like this:
entry_lock_id serial NOT NULL,
entry_id text NOT NULL,
"timestamp" date,
CONSTRAINT entry_lock_pkey PRIMARY KEY (entry_lock_id),
CONSTRAINT entry_entry_lock_fkey FOREIGN KEY (entry_id)
REFERENCES entries (entry_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
I was hoping that adding ON UPDATE CASCADE would achieve the desired effect, but the column in Entries is not getting updated as I would like. How can I achieve the desired behaviour?
I have two tables TABLE_ACCOUNT and TABLE_ACTYPE.
The TABLE_ACCOUNT has columns
(CODE, NAME, TRADE, CATGORY, ACTYPE)
and the TABLE_ACTYPE has columns
(CODE, NAME, ITYPE)
The data in the TABLE_ACTYPE is:
CODE NAME ITYPE
-----------------------
1 TRADE1 1
1 CAT1 2
1 ACT1 3
Primary key for this table is CODE, TYPE
The data in the TABLE_ACCOUNT is :
CODE, NAME, TRADE, CATEGORY, ACTYPE
-----------------------------------
1 Name1 1 1 1
I want to create the 3 foreign keys for to table_account
ALTER TABLE TABLE_ACCOUNT WITH CHECK
ADD CONSTRAINT FK_TABLE_ACCOUNT_TABLE_ACTYPE_TRADE
FOREIGN KEY ([TRADE,1]) REFERENCES [TABLE_ACTYPE] (CODE, ITYPE)
ALTER TABLE TABLE_ACCOUNT WITH CHECK
ADD CONSTRAINT FK_TABLE_ACCOUNT_TABLE_ACTYPE_CAT
FOREIGN KEY ([TRADE,2]) REFERENCES [TABLE_ACTYPE] (CODE, ITYPE)
ALTER TABLE TABLE_ACCOUNT WITH CHECK
ADD CONSTRAINT FK_TABLE_ACCOUNT_TABLE_ACTYPE_ACTYPE
FOREIGN KEY ([TRADE,3]) REFERENCES [TABLE_ACTYPE] (CODE, ITYPE)
Is this possible??
No.
In my SSIS/DW project, I have a DIM.DATE dimension which is linked to my FACT table by a surrogate key as follows:
ALTER TABLE FACT.SALES ADD date_id INT NOT NULL
ALTER TABLE FACT.SALES WITH CHECK ADD CONSTRAINT FK_dim_date FOREIGN KEY (date_id) REFERENCES DIM.DATE(date_id)
This creates a "date_id" in my fact table, now during my SSIS import process I have a date column being passed (shipped_date), I use this to look up the DIM.DATE table and pass in the surrogate key in my dimension.
This works great, but now I need to have a few different date dimensions for invoice date, received date, etc.
I am confused as to how to make use of the existing DIM.DATE to do this?
I could then add more columns into my fact table..
-- add column into fact table
ALTER TABLE FACT.SALES ADD shipped_date_id INT NOT NULL
ALTER TABLE FACT.SALES ADD invoice_date_id INT NOT NULL
-- add foreign key
ALTER TABLE FACT.SALES WITH CHECK ADD CONSTRAINT FK_shipped_date FOREIGN KEY (shipped_date_id) REFERENCES DIM.DATE(date_id)
ALTER TABLE FACT.SALES WITH CHECK ADD CONSTRAINT FK_invoice_date FOREIGN KEY (invoice_date_id) REFERENCES DIM.DATE(date_id)
But when I do my lookup, I can only pass in the "date_id" column.. I am confused how to make this work all together.
Anyone able to clear this up for me?
You have to use multiple LookUp transforms... 1 for each DateKey field in the fact table.