In this code, I have an insert button that will take in the user's input from the textbox and store it in the database. I know the code works as intended with the other tables that have no Foreign Keys in them, but this one does and I'm not sure how to handle it. Everytime it tries to insert CustomerID, the Foreign Key, I keep getting the following error, System.Data.SqlClient.SqlException: 'The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Orders_Customers". The conflict occurred in database "northwind", table "dbo.Customers", column 'CustomerID'.
Below is the insert button code and an image of the program running.
private void button9_Click(object sender, EventArgs e)
{
Order od = new Order
{
OrderID = int.Parse(ordertxt.Text),
CustomerID = customertxt.Text
};
db.Orders.InsertOnSubmit(od);
try
{
db.SubmitChanges();
}
catch (Exception)
{
MessageBox.Show("Invalid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
db.SubmitChanges();
}
display_order();
Program Running
The value that you are inserting into the CustomerID column does not exist in your Customer table, so it cannot be inserted as a foreign key. You could either add logic to validate the value against the Customer table before inserting, and create a new customer if needed, or alter the column so that it is no longer a foreign key if you do not need it to act as such.
My problem might be a bit long to describe as the project we are working on is a bit bigger, but i will try to be as precise as i can.
Basically we're developing a web-bases woundmanagement (part of a project for university) where the user can enter wounds and set additional information like size, consistence, upload a picture, choose the location, ... .
All those information should be stored in a database (we're working with MS SQL Studio and Visual Studio 2017) where the user can also retrieve it later to view it on the module.
The problem we are facing now is that if we want to show a wound to a special wound to the user, we can't get the foreign keys to work.
We can filter via the casenumber (which is working) but we can't filter wound information by the ID of the wound (each wound is getting an unique ID) - so if we choose a wound, we still get information about ALL wounds which are stored for the given casenr.
This is our "main-table" where each wound is getting an unique ID which is also an ascending identity column:
[wound_id] INT IDENTITY (1, 1) NOT NULL,
[wound_type] VARCHAR (500) NULL,
[wound_description] VARCHAR (500) NULL,
[decuGrade] INT NULL,
[wound_comments] VARCHAR (500) NULL,
[wound_timeReal] DATETIME NULL,
[wound_timeGiven] DATETIME NULL,
[casenumber] INT NULL,
[username] VARCHAR (50) NULL,
PRIMARY KEY CLUSTERED ([wound_id] ASC)
);
If the user enters the information and clicks "Next", a function is called in code behind which fills the table:
_db.SaveWoundDetails(casenr, woundValue, decu, additional_info, realTime, givenBackDocDate, user);
This leads to our database-class, where we have our queries for the database, in this case:
public void SaveWoundDetails(int casenr, string woundType, int decuGrade, string woundComment, DateTime timeReal, DateTime timeGiven , string user)
{
var table = ConfigurationManager.AppSettings["woundDetailsTable"];
var insertQuery = "INSERT INTO " + table + "(casenumber, wound_type, decuGrade, wound_comments, wound_timeReal, wound_timeGiven, username) VALUES (#casenr, #woundType, #decuGrade, #woundComment, #timeReal, #timeGiven, #user)";
var cmd = new SqlCommand(insertQuery);
cmd.Parameters.AddWithValue("#casenr", casenr);
cmd.Parameters.AddWithValue("#woundType", woundType);
cmd.Parameters.AddWithValue("#decuGrade", decuGrade);
cmd.Parameters.AddWithValue("#woundComment", woundComment);
cmd.Parameters.AddWithValue("#timeReal", timeReal);
cmd.Parameters.AddWithValue("#timeGiven", timeGiven);
cmd.Parameters.AddWithValue("#user", user);
var db = DatabaseController.getDataBaseController();
try
{
var sqlcmd = db.executeSQL(cmd);
}
catch (SqlException e)
{
}
}
The connection etc. is in a Database-handler class which is not relevant at the moment.
Until here it works fine. But now we have a second table for more information about the wound, which is also filled on next click, related to this table:
CREATE TABLE [dbo].[epadoc_mod_wound_progress] (
[progress_id] INT IDENTITY (1, 1) NOT NULL,
[wound_length] INT NULL,
[wound_width] INT NULL,
[wound_depth] INT NULL,
[wound_surrounding] VARCHAR (500) NULL,
[wound_consistence] VARCHAR (500) NULL,
[wound_state] VARCHAR (200) NULL,
[wound_painscale] VARCHAR (MAX) NULL,
[wound_itch] VARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([progress_id] ASC)
With the INSERT-METHOD:
public void SaveWoundProgress(int woundLength, int woundWidth, int woundDepth, string woundSurrounding, string woundConsistence, string woundState, string woundPainScale, string woundItch)
{
var table = ConfigurationManager.AppSettings["woundProgressTable"];
var insertQuery = "INSERT INTO " + table + "(wound_length,wound_width,wound_depth, wound_surrounding, wound_consistence, wound_state, wound_painscale, wound_itch) VALUES (#woundLength, #woundWidth, #woundDepth, #woundSurrounding, #woundConsistence, #woundState, #woundPainScale, #woundItch)";
var cmd = new SqlCommand(insertQuery);
cmd.Parameters.AddWithValue("#woundLength", woundLength);
cmd.Parameters.AddWithValue("#woundWidth", woundWidth);
cmd.Parameters.AddWithValue("#woundDepth", woundDepth);
cmd.Parameters.AddWithValue("#woundSurrounding", woundSurrounding);
cmd.Parameters.AddWithValue("#woundConsistence", woundConsistence);
cmd.Parameters.AddWithValue("#woundState", woundState);
cmd.Parameters.AddWithValue("#woundPainScale", woundPainScale);
cmd.Parameters.AddWithValue("#woundItch", woundItch);
var db = DatabaseController.getDataBaseController();
try
{
var sqlcmd = db.executeSQL(cmd);
}
catch (SqlException e)
{
}
}
And the method
_db.SaveWoundProgress(wound_length, wound_width, wound_depth, woundArea, woundEdge, woundStatus, painStatus, itchStatus);
which is execute right after the method mentioned above.
I know how to create foreign keys between two tables, but everything we tried failed - if we try to execute it with a foreign key set which is NOT NULL, we're getting a null-exception.
Example of what we tried:
CONSTRAINT [FK_epadoc_mod_wound_details] FOREIGN KEY ([wound_id])
REFERENCES [dbo].[epadoc_mod_wound_progress] ([progress_id])
If we set a foreign key like this, it didn't work.
We came to the conclusion that it must be a problem the callstack when the two methods are executed - but we don't know how we can fix it.
Maybe we have to set the foreign key in the INSERT-query as an explicit variable?
What we want to achieve is that the wound_id of the details-table is taken as foreign key the the progress-table so that a wound can be later changed (for example if it heals the user could re-enter the new size etc.) and we can filter by ID to just show ONE wound to the patient and not all wounds at the same time if clicked on a specific wound.
Sadly i'm not the big database expert so i hope that you can follow my explanations :).
Thanks for any help!
Your epadoc_mod_wound_progress needs to include a [wound_id] INT NOT NULL column. This is what your foreign key should be built on so that one wound can have many wound progresses. Then, in your insert statement, you'll insert the wound_id that generates in woundDetail table insert into epadoc_mod_wound_progress.
Tried to add a comment but I don't have 50 reputation.
I assume from what I can see that you are trying to achieve a one to many relationship between the "main table" and the "epadoc_mod_wound_progress" table, is that right ?
If so, you don't seem to have a field in the "epadoc_mod_wound_progress" table that stores the wound_id, how are you trying to create a foreign key if you are not storing the wound_id ?
Suggest the Primary Key of the epadoc_mod_wound_progress table is a concatenated key of wound_id and progress_id, with wound_id also being the foreign key linking to the main table.
In table epadoc_mod_wound_progress there must be a wound_id INT NOT NULL column acting as foreign key.
Also the constraint must be added to the foreign key table, i.e. the table on the n side of the 1 to n relation. Assuming that the name of the main table is epadoc_mod_wound_details (you did not show it):
ALTER TABLE dbo.epadoc_mod_wound_progress
ADD CONSTRAINT FK_progress_details FOREIGN KEY (wound_id)
REFERENCES dbo.epadoc_mod_wound_details (wound_id)
ON DELETE CASCADE
Also, by adding ON DELETE CASCADE the progress of a wound detail will automatically be deleted when you delete the wound detail.
I'm developing a WinForm desktop application for users to input employees retirement data, using SQL Server 2008 as DB.
One of the tables that gets part of the user data has a reference to another table whose records were defined at design time, adding a Foreign Key constraint for consistency.
CREATE TABLE tbCongedo (
ID int IDENTITY(0,1) PRIMARY KEY,
ID_ANAGRAFICA int NOT NULL,
ID_TIPOLOGIA int NOT NULL,
DECORRENZA datetime NOT NULL,
PROT_NUM nvarchar(7) NOT NULL,
PROT_DATA datetime NOT NULL
);
CREATE TABLE tbTipologia (
ID int IDENTITY(0,1) PRIMARY KEY,
TIPOLOGIA nvarchar(20)
);
INSERT INTO tbTipologia VALUES ('CONGEDO'), ('POSTICIPO'), ('ANTICIPO'), ('REVOCA'), ('DECESSO')
ALTER TABLE tbCongedo
ADD CONSTRAINT FK_tbCongedo_tbTipologia
FOREIGN KEY (ID_TIPOLOGIA) REFERENCES tbTipologia(ID)
Then, I have this code that should execute the INSERT statement
public int Insert(SqlConnection Connessione)
{
using (SqlCommand Comando = new SqlCommand("INSERT INTO tbCongedo VALUES (#ID_ANAGRAFICA, #PROT_NUM, #PROT_DATA, #DECORRENZA, #ID_TIPOLOGIA); SELECT SCOPE_IDENTITY()", Connessione))
{
Comando.Parameters.AddWithValue("#ID_ANAGRAFICA", ID_ANAGRAFICA);
Comando.Parameters.AddWithValue("#PROT_NUM", PROT_NUM);
Comando.Parameters.AddWithValue("#PROT_DATA", PROT_DATA);
Comando.Parameters.AddWithValue("#DECORRENZA", DECORRENZA);
Comando.Parameters.AddWithValue("#ID_TIPOLOGIA", ID_TIPOLOGIA);
ID = Int32.Parse(Comando.ExecuteScalar().ToString());
}
return ID;
}
but I'm given this SqlException:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_tbCongedo_tbTipologia". The conflict occurred in database "Scadenziario_ver4_TEST", table "dbo.tbTipologia", column 'ID'
These are the data that I was trying to get inserted in the table:
ID_ANAGRAFICA = 2
ID_TIPOLOGIA = 0
PROT_DATA = {16/03/2018 00:00:00}
DECORRENZA = {16/03/2018 00:00:00}
PROT_NUM = 123456
Funny thing is that when I try to insert those same data manually through SQL Server Management Studio, I'm given no error at all.
Thanks.-
Try specifying fields: (col_name1, col_name2, ...).
Without that the VALUES may not be applied as how you might hope. Variable names are NOT automagically matched with similarly-named columns.
So like this:
... new SqlCommand
(
"INSERT INTO tbCongedo " +
" (ID_ANAGRAFICA, PROT_NUM, PROT_DATA, DECORRENZA, ID_TIPOLOGIA) "
"VALUES (#ID_ANAGRAFICA, #PROT_NUM, #PROT_DATA, #DECORRENZA, #ID_TIPOLOGIA); " +
"SELECT SCOPE_IDENTITY()", Connessione
)
...
I think the problem isn't in the data but in the INSERT statement itself. You are trying to insert the values to the wrong columns using the wrong order. To solve the issue you should either specify the columns in the INSERT statement or correct the order of the values. In your case the query will try to insert the value of #PROT_NUM in the ID_TIPOLOGIA instead.
I have two tables in my DB
Collection_ ( #Id_Collection, Libelle_Collection, Id_Editeur_Editeur )
Editeur ( #Id_Editeur, Libelle_Editeur )
When I want to delete some record from the table "Editeur", it gives me this error:
The DELETE statement conflicted with the REFERENCE constraint
"FK_Collection_Id_Editeur_Editeur". The conflict occurred in database
"Gestion_bib", table "dbo.Collection_", column 'Id_Editeur_Editeur'.
The statement has been terminated.
I know that the error because the foreign key in the Collection_ table is a PK in the Editeur table, I was using the Cascade statement in another DB but i had problems with it so I don't prefer to work with it also I used another method using ADO.Net :
for (int i = 0; i < myClass.ds.Tables["Collection_"].Rows.Count; i++)
if (valToDelete == myClass.ds.Tables["Collection_"].Rows[i][2].ToString())
myClass.ds.Tables["Collection_"].Rows[i][2] = DBNull.Value;
SqlCommandBuilder cmb = new SqlCommandBuilder(adapter);
adapter.Update(myClass.ds, "Editeur");
but this method is getting complicated when I handle with tables that contains many FK.
So, please is there any other method to change the FK to the Null Value if I deleted the table which contains the PK ??
Try doing this using SQL Query:
Update Collection_ SET Id_Editeur_Editeur = NULL WHERE Id_Editeur_Editeur IN
(CommaSeperatedValuesToDelete);
Then,
Delete From Editeur Where Id_Editeur IN (CommaSeperatedValuesToDelete);
I have the following function to update and insert a record in the table
public DASInput UpdateDASInputTable(DASInput fileSetData, Guid programID)
{
string connectionString = GetConnectionString(programID);
BI_ProgramConfigurationEntities dataContext = new BI_ProgramConfigurationEntities(connectionString);
dataContext.DASInputs.ApplyChanges(fileSetData);
dataContext.SaveChanges(System.Data.Objects.SaveOptions.DetectChangesBeforeSave);
fileSetData = dataContext.DASInputs.FirstOrDefault();
return fileSetData;
}
When I make first call with a new object of type DASInput, then it gets inserted correctly in the database. (DASInput table has the primary key as int with identity specification on).
But this first time insertion does not return the modified value of the primary key of the DASInput table.
So on every subsequent call a new record gets inserted in the database. I want the primary key(self generated by DB) to be returned to the client when the record gets inserted.
Isn't the syntax for adding an entity into a linq controlled database more along the lines of :
context.Table.AddObject(newStore);
//or
context.Table.Add(newStore);
context.SaveChanges();
I do answer this tentatively, not being hugely knowledgeable on LINQ.