The INSERT statement conflicted with the FOREIGN KEY constraint "FK_ - c#

I have two tables , one to one relationship i makes DetailsID of projectDetails FK in ID of projects table:
projects:
ID, //has FK With DetailsID in Details table & auto identity (1,1)
ProjectName,
Areas,
PaymentSystem,
ReceivedDate,
PropertyClassification,
ProjectImage
ProjectDetails:
DetailsID ,auto identity ( 1,1)
ProjectDetailName,
ProjectDetailImage
I am trying to insert new record in projects table , gives me this error at this line of code :
con.Open();
comm.ExecuteNonQuery(); // when execute
System.Data.SqlClient.SqlException: 'The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Projects_ProjectDetails". The conflict occurred in database "AlamaarRealEstate", table "dbo.ProjectDetails", column 'DetailsID'.
and this is my stored to insert :
ALTER proc [Insert_Project]
#Projectname NVARCHAR(MAX) ,
#areas NVARCHAR(MAX) ,
#Paymentsystem NVARCHAR(MAX) ,
#Receiveddate date ,
#Classification NVARCHAR(MAX) ,
#Projectimage Nvarchar(MAX)
as
INSERT INTO dbo.Projects
(
ProjectName,
Areas,
PaymentSystem,
ReceivedDate,
PropertyClassification,
ProjectImage
)
VALUES
(
#Projectname ,
#areas,
#Paymentsystem ,
#Receiveddate ,
#Classification,
#Projectimage
)

The question explains the answer. Referential Integrity is not maintained properly, you are trying to insert into a child table for which the master value does not exist. Please insert values to Project_details first. This will resolve your issue. If you did not what this to throw an error, just check the existence of the DetailID in Projects table before inserting.

Without more detail your question is hard to answer. For instance in your procedure you do explicit column naming for inserts and LEAVE OUT the column you are having a problem with. So if the proc was wrong it would be bombing with your example foreign key constraint error. But you are not even listing the 'ID' field to insert into with the procedure. So this is common if you are using an 'Identity' field to self seed, but you are claiming it is a foreign key. So like others have commented, without more code to show the exact way your tables are made it's hard to guess. Here is a self extracting example you could run that shows if a column is nullable and I had a key constraint it would work. Without the exact code of the tables as well as the proc it is hard to tell. What you gave is pseudo code.
USE Tester --just a test database I have, you can use whatever database you want
GO
IF OBJECT_ID('Projects') IS NOT NULL
DROP TABLE Projects
IF OBJECT_ID('ProjectDetails') IS NOT NULL
DROP TABLE ProjectDetails
create TABLE ProjectDetails
(
DetailsID INT CONSTRAINT PK_DetailsId PRIMARY KEY,
ProjectDetailName VARCHAR(32)
)
CREATE TABLE Projects
(
Id INT CONSTRAINT FK_Projects_ProjectDetails FOREIGN KEY (Id) REFERENCES ProjectDetails(DetailsId),
ProjectName varchar(32)
)
GO
IF OBJECT_ID('Insert_Project') IS NOT NULL
DROP PROC Insert_Project
GO
Create proc Insert_Project
#Projectname NVARCHAR(MAX)
as
INSERT INTO dbo.Projects ( ProjectName )
VALUES ( #Projectname )
GO
Select *
From dbo.Projects
EXEC dbo.Insert_Project #Projectname = N'Test' -- nvarchar(max)
Select *
From dbo.Projects

Related

SQL may cause cycles or multiple cascade paths

I edited the whole question because i managed to find what triggers the error so i just leave the SQL approach since it's easy to test
may cause cycles or multiple cascade paths. Specify ON DELETE NO
ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY
constraints.
DROP TABLE dbo.ProductionUnits
CREATE TABLE ProductionUnits
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(50)
)
DROP TABLE Cells
CREATE TABLE Cells
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(10),
ProductionUnitId INT FOREIGN KEY REFERENCES ProductionUnits(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
DROP TABLE CheckLists
CREATE TABLE CheckLists
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(20),
CellId INT FOREIGN KEY REFERENCES Cells(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
DROP TABLE CheckListGroups
CREATE TABLE CheckListGroups
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(20),
CheckListId INT FOREIGN KEY REFERENCES CheckLists(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
DROP TABLE CheckListGroupItems
CREATE TABLE CheckListGroupItems
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(20),
CheckListGroupId INT FOREIGN KEY REFERENCES CheckListGroups(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
DROP TABLE Shifts
CREATE TABLE Shifts
(
Id INT PRIMARY KEY IDENTITY,
StartTime TIME,
EndTime TIME,
ShiftDescription NVARCHAR(20),
ProductionUnitId INT FOREIGN KEY REFERENCES ProductionUnits(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
DROP TABLE ProductionRecords
CREATE TABLE ProductionRecords
(
Id INT PRIMARY KEY IDENTITY,
CreatedOn DATETIME,
CreatedBy NVARCHAR(50),
ModifiedOn DATETIME,
ModifiedBy NVARCHAR(50)
)
DROP TABLE dbo.Referencias
CREATE TABLE Referencias
(
Id INT PRIMARY KEY IDENTITY,
Name NVARCHAR(15),
)
DROP TABLE dbo.CheckListRecords
CREATE TABLE CheckListRecords
(
Id INT PRIMARY KEY IDENTITY,
Value NVARCHAR(3),
ReferenciaId INT FOREIGN KEY REFERENCES Referencias(Id) ON DELETE CASCADE ON UPDATE CASCADE,
ShiftId INT FOREIGN KEY REFERENCES Shifts(Id) ON DELETE CASCADE ON UPDATE CASCADE,
CheckListGroupItemId INT FOREIGN KEY REFERENCES dbo.CheckListGroupItems(Id) ON DELETE CASCADE ON UPDATE CASCADE,
ProductionRecordsId INT FOREIGN KEY REFERENCES ProductionRecords(Id) ON DELETE CASCADE ON UPDATE CASCADE
)
So the problem is when I add
CheckListGroupItemId INT FOREIGN KEY REFERENCES dbo.CheckListGroupItems(Id) ON DELETE CASCADE ON UPDATE CASCADE,
But i need this to know which item belongs to but this works if i delete the ON DELETE CASCADE
I'm not very experienced to SQL when it comes to foreign keys and handling cascade paths-
What should I do in this situation?
There are two paths to deleting CheckListRecords when you delete a ProductionUnits row. This is what it's complaining about.
ProductionUnits ->
Cells ->
CheckLists ->
CheckListGroups ->
CheckListGroupItems ->
CheckListRecords
...and...
ProductionUnits ->
Shifts ->
CheckListRecords
Bummer - you can't have that...an there's no real simple way to get around it :-(
It's a common occurrence. But, have hope - there's a reasonable way to deal with it...that isn't too awful. When you get a message like that, work your way backwards from the table it's griping about...and when you find multiple ON DELETE CASCADE columns in the delete path that point to the same table, you've found your culprit.
Before I suggest a solution, a couple of observations: for one thing, you've got Ids that are identity-generated. So, On Update Cascade probably shouldn't be specified in such a world because the IDs can't readily change (unless you're behaving very badly somewhere).
Another minor best-practice kinda note: specify the schema when creating the tables:
CREATE TABLE dbo.ProductionUnits
(
-- etc.
)
...and always use the schema when referring to the table in views and procedures.
Okay - so how to deal with the conflict? What you might consider doing is removing the foreign key from CheckListRecords to Shifts and instead, implement a delete trigger on Shifts that deletes the affected CheckListRecords rows. A long time ago...before there was declarative referential integrity, you had to deal with managing the relationships with triggers. It still comes in handy in places like this.
Assuming you've added the schema to the table declarations, it would be something roughly like:
create trigger [Shifts.Delete.Trigger] on dbo.Shifts for delete as
begin
set nocount on;
delete dbo.CheckListRecords where ShiftId in ( select Id from deleted );
end
See, that wasn't so bad, eh?
If you just have to update Shifts.Id for some reason, it gets a bit more complicated. You would have to have an alternate key on the Shifts table in order to implement the logic...preferably a column that you never update or at least one that is not updated when the Id gets changed. Maybe the StartTime column? You could add a uniqueidentifier column if you don't have a candidate key. For example:
CREATE TABLE Shifts
(
Id INT PRIMARY KEY IDENTITY,
StartTime TIME,
EndTime TIME,
ShiftDescription NVARCHAR(20) ,
ProductionUnitId INT FOREIGN KEY REFERENCES ProductionUnits(Id) ON DELETE CASCADE ON UPDATE CASCADE,
RowId UNIQUEIDENTIFIER
CONSTRAINT [Shifts.RowId.Default] DEFAULT ( NEWID() )
CONSTRAINT [Shifts.RowId.Unique] UNIQUE
)
Most of your views and logic would just completely ignore this column. You don't even need to let EF see it. With how I declared it, it gets set automatically on insert (similar to identity columns).
The only code that uses RowId is the update trigger:
create trigger [Shifts.Update.Trigger] on dbo.Shifts for update as
begin
set nocount on;
if update( Id ) --> just skip everything if the Id did not change
begin
update dbo.CheckListRecords
set ShiftId = i.Id
from
inserted i
inner join
deleted d
on
i.RowId = d.RowId
inner join
dbo.CheckListRecords c
on
c.ShiftId = d.Id
end
end
It's not super horrible...but not ideal. Really, if you don't have any reason to update the ID columns (and you really really shouldn't), you can skip all of this update trigger and extra column nonsense.
I think, if you have trigger-based referential integrity, you have to tell EF about it...but EF is not the way of my people...so I can't help with that particular point. But I'm almost certain it's a fairly simple declaration when you describe your data model to EF.

Relationship between Identity tables and Other tables in ASP.NET MVC 5

In ASP.NET MVC 5 project, the database and identity tables are created by code first, and i created other tables by SQL (not by code first) in this database, and i want to join User table with some table by user Id.
Say database called Qwerty and the identity tables are:
dbo.Users
dbo.Roles
dbo.UserClaims
... ect
I want to create tables by SQL like this:
Create Table Topic.Topic
(
TopicID int Primary key identity(1,1) not null,
TopicAddress nvarchar(255) not null
)
Create Table dbo.Bookmark
(
BookmarkID int Primary key identity(1,1) not null,
BookmarkDate datetime default getdate() not null,
UserID int constraint FK_Favorites_Users_UserID foreign key (UserID) references Users(UserID) not null
)
Topic table is created successfully, but when i run SQL code for Bookmark table, it give me error and mark Users (table name) word with red line
By default the primary key of Users is nvarchar, so, your foreign key should be defined with that type.
Create Table dbo.Bookmark
(
BookmarkID int Primary key identity(1,1) not null,
BookmarkDate datetime default getdate() not null,
UserID [nvarchar](128) constraint FK_Favorites_Users_UserID foreign key (UserID) references Users(UserID) not null
)

"The INSERT statement conflicted with the FOREIGN KEY constraint" when insert is NULL

I have this problem: I have this table which has 5 columns: ID, Usuario_IdUsuario, Artista_IdArtista, Disco_IdDisco, Lista_IdLista. The last 4 are foreign keys, and the last 2 allow nulls, because at the time of their creation, the tables they are referencing are empty. So I insert Usuario_IdUsuario and Artsita_IdArtista and I get the following message:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Sigue_Lista". The conflict occurred in database "Tarea2", table "dbo.Lista", column 'IdLista'.
The statement has been terminated.
But that table is empty, and not inserting anything there, since it allows nulls. I already checked, it does not have a default value.
Note: This might be considered as "Duplicate" but the answers given in previous questions don't work for me and I can't comment to ask what happens if that doesn't work (default value thing).
The insert code where the problem appears:
string insertQuery2 = "insert into Sigue (Usuario_IdUsuario, Artista_IdArtista) values (#usu, #Artista);"; //if I delete the ; inside the "", then it doesn't show any error messages, but it doesn't isert anything into the table either.
SqlCommand sig = new SqlCommand(insertQuery2, conn);
sig.Parameters.AddWithValue("#usu", idusu); //UserId taken from user table
sig.Parameters.AddWithValue("#Artista", idar); //ArtistId taken from artist table.
sig.ExecuteNonQuery();
What am I doing wrong?
(I'm working with C# on Visual Studio 2012 and also using SQL Server 2012 with Management Studio)
USE [Tarea2]
GO
/****** Object: Table [dbo].[Sigue] Script Date: 02-11-2014 20:32:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sigue](
[IdSigue] [int] IDENTITY(1,1) NOT NULL,
[Usuario_IdUsuario] [int] NOT NULL,
[Artista_IdArtista] [int] NOT NULL,
[Disco_IdDisco] [int] NULL,
[Lista_IdLista] [int] NULL,
CONSTRAINT [PK_Sigue] PRIMARY KEY CLUSTERED
(
[IdSigue] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Sigue] ADD CONSTRAINT [DF_Sigue_Disco_IdDisco] DEFAULT (NULL) FOR [Disco_IdDisco]
GO
ALTER TABLE [dbo].[Sigue] ADD CONSTRAINT [DF_Sigue_Lista_IdLista] DEFAULT (NULL) FOR [Lista_IdLista]
GO
ALTER TABLE [dbo].[Sigue] WITH CHECK ADD CONSTRAINT [FK_Sigue_Artista] FOREIGN KEY([Artista_IdArtista])
REFERENCES [dbo].[Artista] ([IdArtista])
GO
ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Artista]
GO
ALTER TABLE [dbo].[Sigue] WITH CHECK ADD CONSTRAINT [FK_Sigue_Disco] FOREIGN KEY([Disco_IdDisco])
REFERENCES [dbo].[Disco] ([IdDisco])
GO
ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Disco]
GO
ALTER TABLE [dbo].[Sigue] WITH CHECK ADD CONSTRAINT [FK_Sigue_Lista] FOREIGN KEY([Lista_IdLista])
REFERENCES [dbo].[Lista] ([IdLista])
GO
ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_Lista]
GO
ALTER TABLE [dbo].[Sigue] WITH CHECK ADD CONSTRAINT [FK_Sigue_UserData] FOREIGN KEY([Usuario_IdUsuario])
REFERENCES [dbo].[UserData] ([Id])
GO
ALTER TABLE [dbo].[Sigue] CHECK CONSTRAINT [FK_Sigue_UserData]
GO
ALTER TABLE [dbo].[Sigue]
WITH CHECK ADD CONSTRAINT [FK_Sigue_Lista] FOREIGN KEY([IdSigue])
REFERENCES [dbo].[Lista] ([IdLista])
Should be
ALTER TABLE [dbo].[Sigue]
WITH CHECK ADD CONSTRAINT [FK_Sigue_Lista] FOREIGN KEY(Lista_IdLista)
REFERENCES [dbo].[Lista] ([IdLista])
You are validating the wrong column. Currently the behaviour is that it will validate the value in IdSigue appears in [dbo].[Lista]. This isn't the correct semantics.
The same error appears in most of your other FK definitions too.
Try explicitly setting the two columns to NULL like this:
INSERT INTO Sigue (Usuario_IdUsuario, Artista_IdArtista, Disco_IdDisco, Lista_IdLista) VALUES (#usu, #Artista, NULL, NULL);
According to the following links, this should work:
set null value in a foreign key column?
Can table columns with a foreign key be null?
Since you mentioned, that the column does NOT have a default value set, you can also try to set the default value to NULL instead.
You can see in this little SQL Fiddle, that inserting NULL into foreign keys is not a problem at all.
After question was edited:
Now, that you provide the info on how you created the foreign keys: You are creating all four foreign keys on the same column IdSigue.
The ALTER TABLE statements should be changed from:
ALTER TABLE [dbo].[Sigue]
WITH CHECK ADD CONSTRAINT [FK_Sigue_Artista]
FOREIGN KEY([IdSigue]) REFERENCES [dbo].[Artista] ([IdArtista])
to:
ALTER TABLE [dbo].[Sigue]
WITH CHECK ADD CONSTRAINT [FK_Sigue_Artista]
FOREIGN KEY([Artista_IdArtista]) REFERENCES [dbo].[Artista] ([IdArtista])
The difference is in the () after FOREIGN KEY.
Do this for the other three foreign key definitions as well.
Last but not least a couple of links on the topic:
How do I create a foreign key in SQL Server?
http://www.sqlinfo.net/sqlserver/sql_server_Create_foreign_key_contraints.php

How to set a column equal to the Primary key?

How can I get the primary key value and put it in another column when I insert the data?
Here is my table schema:
CREATE TABLE IF NOT EXISTS [MyTable] (
[ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[custom_ID] INTEGER NULL,
[Name] VARCHAR (200) NULL)
The query I have so far is:
INSERT INTO MyTable (custom_ID, Name)
values (
' {Here I need to get the primary key value, and then put it in custom_ID} ',
'someName')
Thanks!
Don't do that. You are violating all sorts of good database design principles by going this route. The primary key is supposed to represent the data that unique identifies a tuple (row). When you start having multiple copies of your primary key, you in turn defeat the entire purpose of the key.
As suggested by Chris:
CREATE TRIGGER MyTable_CustomID AFTER INSERT ON MyTable WHEN NEW.Custom_ID=NULL BEGIN
UPDATE MyTable SET Custom_ID=NEW.Id WHERE ROWID=NEW.ROWID;
END;
As far I can say you are trying to generate some custom Id based upon the PK. Like if my PK = 1 then you need a custom Id as ABCDEF/000/1 . So in that case you have to pick the immediate Id generate by the insert query and then run a update statement either in a trigger or just after the insert statement. Since its sql lite so you need to research a little bit to get identity similar to Scope_Identity() or ##Identity in Sql Server.
Try something like this:
insert [Order] (col1, col2, ...) values ('val1', 'val2', ...) -- Note: no ID is specified
declare #id int = scope_identity()
insert OrderDetail (order_id, col1, ...) values (#id, 'val1', ...)

deadlock when SQL Server transaction log ever-increase?

I am using SQL Server 2008 Enterprise. I have tried that if I set SQL Server transaction log to ever increase for the related database (with no backup settings), then a single delete statement of this stored procedure will cause deadlock if executed by multiple threads at the same time? Any ideas why?
For the delete statement, Param1 is a column of table FooTable, Param1 is a foreign key of another table (refers to another primary key clustered index column of the other table). There is no index on Param1 itself for table FooTable. FooTable has another column which is used as clustered primary key, but not Param1 column.
create PROCEDURE [dbo].[FooProc]
(
#Param1 int
,#Param2 int
,#Param3 int
)
AS
DELETE FooTable WHERE Param1 = #Param1
INSERT INTO FooTable
(
Param1
,Param2
,Param3
)
VALUES
(
#Param1
,#Param2
,#Param3
)
DECLARE #ID bigint
SET #ID = ISNULL(##Identity,-1)
IF #ID > 0
BEGIN
SELECT IdentityStr FROM FooTable WHERE ID = #ID
END
As a rule of thumb, you should always create an index on the column that has FOREIGN KEY constraint. Otherwise, deadlock is very likely to happen (because the server has to lock the whole dependent table to ensure that constraint)

Categories