I have 2 tables, and I have just done an insert of about 1,000,000 rows. I turned off foreign key constraints , but I have an error when I try and reinstate them with
ALTER TABLE ForexRebatesNow.dbo.Transactions WITH CHECK CHECK CONSTRAINT ALL
I get the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Transactions_RebateAccounts". The conflict occurred in database "ForexRebatesNow", table "dbo.RebateAccounts", column 'Id'.
So I go to look for RebateAccountId that does not have a corresponding Id in the RebateAccounts table
SELECT Id
FROM ForexRebatesNow.dbo.RebateAccounts
WHERE Id NOT IN (SELECT RebateAccountId
FROM ForexRebatesNow.dbo.Transactions)
But this returns zero rows, so in my mind that conflict does not exist.
Am I missing something here?
EDIT
The relationship between RebateAccounts and Transactions is One to Many. RebateAccountId is a Nullable int on Transactions table as not allTransactions will have an associated RebateAccount, but any RebateAccount can have many Transactions
As you have not provided the relations between the two tables, I assume that there is a One-to-Many relation between RebateAccounts and Transactions Table. If I'm right then I guess you are checking the conflict in an opposite way. Your foreign key in in the dbo.Transactions table but you are checking it with the dbo.RebateAccounts table.
Try the following query to find the conflict.
SELECT * FROM Transactions WHERE RebateAccountId NOT IN (SELECT Id FROM RebateAccounts)
If any row shows up then that row has an account id that does not belong to any account. That's where your conflict is.
Hope it helps.
Related
I am stumped by an Add Constraint Foreign Key error I am encountering.
I just created TableA with a Primary Key on PLAN_ID. The table contains zero records. I am attemtpting to execute:
alter table TableB
add constraint FK_TASK_PLAN Foreign Key (TASK_PLAN_ID)
references TableA (PLAN_ID)
Which keeps returning
"Msg 547, Level 16, State 0, Line 5. The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_TASK_PLAN". The conflict occurred in database "DT_Worklist", table "dbo.TableA", column 'PLAN_ID'.
This essentially seems to be telling me I cannot create an FK on the specified column.
What am I doing wrong which is preventing me from creating this Foreign Key? Is it OK my Parent Table is empty or does it need at least one record? What about the FK column; does it need to be Not Null or does it need to have at least 1 record?
Actually, I think I figured this out... My PARENT Table which I just created is empty while my CHILD Table which was created * populated about a week ago already has values in the FK column. So there is no way to create the PK/FK relationship when the FK already contains values.....
I'm having a really, really strange issue with postgres. I'm trying to generate GUIDs for business objects in my database, and I'm using a new schema for this. I've done this with several business objects already; the code I'm using here has been tested and has worked in other scenarios.
Here's the definition for the new table:
CREATE TABLE guid.public_obj
(
guid uuid NOT NULL DEFAULT uuid_generate_v4(),
id integer NOT NULL,
CONSTRAINT obj_guid_pkey PRIMARY KEY (guid),
CONSTRAINT obj_id_fkey FOREIGN KEY (id)
REFERENCES obj (obj_id)
ON UPDATE CASCADE ON DELETE CASCADE
)
However when I try to backfill this using the following code, I get a SQL state 23503 claiming that I'm violating the foreign key constraint.
INSERT INTO guid.public_obj (guid, id)
SELECT uuid_generate_v4(), o.obj_id
FROM obj o;
ERROR: insert or update on table "public_obj" violates foreign key constraint "obj_id_fkey"
SQL state: 23503
Detail: Key (id)=(-2) is not present in table "obj".
However, if I do a SELECT on the source table, the value is definitely present:
SELECT uuid_generate_v4(), o.obj_id
FROM obj o
WHERE obj_id = -2;
"0f218286-5b55-4836-8d70-54cfb117d836";-2
I'm baffled as to why postgres might think I'm violating the fkey constraint when I'm pulling the value directly out of the corresponding table. The only constraint on obj_id in the source table definition is that it's the primary key. It's defined as a serial; the select returns it as an integer. Please help!
Okay, apparently the reason this is failing is because unbeknownst to me the table (which, I stress, does not contain many elements) is partitioned. If I do a SELECT COUNT(*) FROM obj; it returns 348, but if I do a SELECT COUNT(*) FROM ONLY obj; it returns 44. Thus, there are two problems: first, some of the data in the table has not been partitioned correctly (there exists unpartitioned data in the parent table), and second, the data I'm interested in is split out across multiple child tables and the fkey constraint on the parent table fails because the data isn't actually in the parent table. (As a note, this is not my architecture; I'm having to work with something that's been around for quite some time.)
The partitioning is by implicit type (there are three partitions, each of which contains rows relating to a specific subtype of obj) and I think the eventual solution is going to be creating GUID tables for each of the subtypes. I'm going to have to handle the stuff that's actually in the obj table probably by selecting it into a temp table, dropping the rows from the obj table, then reinserting them so that they can be partitioned properly.
We have got table which has many rows. I want create foreign key between these two tables but
I get the following error.
'CMEvent' table saved successfully;
'BaseEvent' table
Unable to create relationship 'FK_CMEvent_Oid'.
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_CMEvent_Oid". The conflict occurred in database "CMO_RestoredData", table "dbo.BaseEvent", column 'Oid'.`
I was able to duplicate this error when I had a row in the CMEvent table that did not exist in BaseEvent.
Try running this query:
SELECT *
FROM CMEvent c
WHERE NOT EXISTS (
SELECT *
FROM BaseEvent
WHERE oid = c.oid )
If you get any rows back, these will have to be deleted before you can apply the foreign key constraint.
If you need to keep these orphaned rows, you can use WITH NOCHECK to only apply the constraint to new rows.
Do Foreign Key constraints get checked on an SQL update statement that doesn't update the columns with the Constraint? (In MS SQL Server)
Say I have a couple of tables with the following columns:
OrderItems
- OrderItemID
- OrderItemTypeID (FK to a OrderItemTypeID column on another table called OrderItemTypes)
- ItemName
If I just update
update [dbo].[OrderItems]
set [ItemName] = 'Product 3'
where [OrderItemID] = 2508
Will the FK constraint do it's lookup/check with the update statement above? (even thought the update is not change the value of that column?)
No, the foreign key is not checked. This is pretty easy to see by examining the execution plans of two different updates.
create table a (
id int primary key
)
create table b (
id int,
fkid int
)
alter table b add foreign key (fkid) references a(id)
insert into a values (1)
insert into a values (2)
insert into b values (5,1) -- Seek on table a's PK
update b set id = 6 where id = 5 -- No seek on table a's PK
update b set fkid = 2 where id = 6 -- Seek on table a's PK
drop table b
drop table a
No. Since the SQL update isn't updating a column containing a constraint, what exactly would SQL Server be checking in this case? This is similar to asking, "does an insert trigger get fired if I only do an update?" Answer is no.
There is a case when the FK not existing will prevent updates to other columns even though the FK is not changed and that is when the FK is created WITH NOCHECK and thus not checked at the time of creation. Per Books Online:
If you do not want to verify new CHECK or FOREIGN KEY constraints
against existing data, use WITH NOCHECK. We do not recommend doing
this, except in rare cases. The new constraint will be evaluated in
all later data updates. Any constraint violations that are suppressed
by WITH NOCHECK when the constraint is added may cause future updates
to fail if they update rows with data that does not comply with the
constraint.
I have a database table called Lesson:
columns: [LessonID, LessonNumber, Description] ...plus some other columns
I have another table called Lesson_ScoreBasedSelection:
columns: [LessonID,NextLessonID_1,NextLessonID_2,NextLessonID_3]
When a lesson is completed, its LessonID is looked up in the Lesson_ScoreBasedSelection table to get the three possible next lessons, each of which are associated with a particular range of scores. If the score was 0-33, the LessonID stored in NextLessonID_1 would be used. If the score was 34-66, the LessonID stored in NextLessonID_2 would be used, and so on.
I want to constrain all the columns in the Lesson_ScoreBasedSelection table with foreign keys referencing the LessonID column in the lesson table, since every value in the Lesson_ScoreBasedSelection table must have an entry in the LessonID column of the Lesson table. I also want cascade updates turned on, so that if a LessonID changes in the Lesson table, all references to it in the Lesson_ScoreBasedSelection table get updated.
This particular cascade update seems like a very straightforward, one-way update, but when I try to apply a foreign key constraint to each field in the Lesson_ScoreBasedSelection table referencing the LessonID field in the Lesson table, I get the error:
Introducing FOREIGN KEY constraint 'c_name' on table 'Lesson_ScoreBasedSelection' may cause cycles or multiple cascade paths.
Can anyone explain why I'm getting this error or how I can achieve the constraints and cascading updating I described?
You can't have more than one cascading RI link to a single table in any given linked table. Microsoft explains this:
You receive this error message because
in SQL Server, a table cannot appear
more than one time in a list of all
the cascading referential actions that
are started by either a DELETE or an
UPDATE statement. For example, the
tree of cascading referential actions
must only have one path to a
particular table on the cascading
referential actions tree.
Given the SQL Server constraint on this, why don't you solve this problem by creating a table with SelectionID (PK), LessonID, Next_LessonID, QualifyingScore as the columns. Use a constraint to ensure LessonID and QualifyingScore are unique.
In the QualifyingScore column, I'd use a tinyint, and make it 0, 1, or 2. That, or you could do a QualifyingMinScore and QualifyingMaxScore column so you could say,
SELECT * FROM NextLesson
WHERE LessonID = #MyLesson
AND QualifyingMinScore <= #MyScore
AND #MyScore <= QualifyingMaxScore
Cheers,
Eric