I am attempting to relocate information in my postgresql database during a migration. data stored in one table is being separated into a many with a table linking them via foreign keys.
Old table: itemsInBag
ID
name
baglabel
New tables: item, itemsInBag, bag
item
Id
Name
itemsInBag
Id
ItemId
BagId
bag
Id
BagLabel
Currently I have these SQL statements to try to link them together. This is done after the new tables and fields have been added and before the itemsInBag fields are dropped.#
migrationBuilder.Sql(
"INSERT INTO items (Name)" +
"SELECT (name) FROM itemsInBag");
migrationBuilder.Sql(
"INSERT INTO bag baglabel" +
"SELECT DISTINCT baglabel FROM itemsInBag");
migrationBuilder.Sql(
"UPDATE itemsInBag SET bagid =(SELECT id FROM bag WHERE bag.baglabel = itemsInBag.baglabel)"
);
migrationBuilder.Sql(
"UPDATE itemsInBag SET itemid =(SELECT id FROM items WHERE items.name = itemsInBag.name)"
);
I am receiving this error when trying to run the migration
$exception {"23505: could not create unique index \"IX_itemsinbag_bagid_itemid\""} Npgsql.PostgresException
"Key (bagid, itemid)=(0, 0) is duplicated."
From everything I have read it would seem this is the right way to do it. Is there a better way of doing this? Is there something I am missing?
UPDATE: if I move the unique constraint on bagid and itemid to after the SQL statements i get this error
$exception {"23503: insert or update on table \"itemsinbag\" violates foreign key constraint \"FK_itemsinbag_bag_bagid\""} Npgsql.PostgresException
"Key (bagid)=(0) is not present in table \"bag\"
Figured out the solution to this. It was all a matter of arranging where the Indices and foreign key constraints were in relation to my SQL statements. The Foreign key constraints needed to be created after the tables data had been rearranged. There was also an error after where the items table did not exist on the insert. The schema needed to be included such that the final SQL statements were as follows:
migrationBuilder.Sql(
"INSERT INTO schema.items (Name)" +
"SELECT name FROM schema.itemsInBag");
migrationBuilder.Sql(
"INSERT INTO schema.bag (baglabel)" +
"SELECT DISTINCT baglabel FROM schema.itemsInBag");
migrationBuilder.Sql(
"UPDATE schema.itemsInBag SET bagid =(SELECT id FROM schema.bag WHERE schema.bag.baglabel = schema.itemsInBag.baglabel)"
);
migrationBuilder.Sql(
"UPDATE schema.itemsInBag SET itemid =(SELECT id FROM schema.items WHERE schema.items.name = schema.itemsInBag.name)"
);
Related
So I am writing a C# application and in my database I have a table Subject with columns: SubjectID - PK, ProfessorID - FK, Description, Credits and Name; also a table Professor with columns: ProfessorID - PK, Name, Surname and Salary. I have a problem when I try to update a Subject info and I don't know why. I have set the Update rule to be Cascade. I have tried to find the answer here but couldn't find one.
Here is the command text:
command.CommandText = "UPDATE Subject SET ProfessorID = #ProfessorID, Name = #Name, Description = #Description, Credits = #Credits WHERE SubjectID = #SubjectID ";
command.Parameters.AddWithValue("ProfessorID",Convert.ToInt32(cb.SelectedValue));
command.Parameters.AddWithValue("Name", tbName.Text);
command.Parameters.AddWithValue("Credits", Convert.ToByte(tbCredits.Text));
command.Parameters.AddWithValue("Description", rtb.Text);
if (command.ExecuteNonQuery() > 0) {...} here I get this error:
System.Data.SqlClient.SqlException: 'The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_Subject_Professor". The conflict occurred in database "UNI", table "dbo.Professor", column 'ProfessorID'.
The statement has been terminated.'
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 the following situation:
In my database, I have a table called Person. A person has an ID. In my conceptual model, student is inherited from person, so I have another table called Student.
I wrote C# code to insert into the Student table:
string query = "INSERT INTO Person (ID, ...) VALUES("id",...);";
MySqlCommand command = new MySqlCommand(query, connection);
command.ExecuteNonQuery();
query = "INSERT INTO Student (..., ID) VALUES(...,"id");";
command.ExecuteNonQuery();
Obviously, I need to add values into the Person class first, because every student is a person. So, after I did that, I try to add the rest of the Student data into the table.
The problem is that I am getting this error:
Duplicate entry (id) for key "PRIMARY"
which I don't understand, since this key needs to be the same.
The exception message is pretty clear:
Duplicate entry (id) for key "PRIMARY"
You ARE duplicating the ID on a table.
You didn't tell in which line this is happening, so, let's assume both possibilities (and that the error is not elsewhere).
The exception is happening when you are trying to insert into table PERSON.
In this case,if the PRIMARY KEY of this table was AUTO INCREMENT, this wouldn't be possible. If it isn't, and you are inserting the ID of the record by yourself, your code is not creating the ID's correctly and is inserting a value that already exists in the table.
To check if this is the case during runtime, just make a select for the ID you are trying to insert BEFORE actually inserting it:
string query = "SELECT count(*) FROM Person WHERE ID = " + id;
MySqlCommand command = new MySqlCommand(query, connection);
int count = (int)command.ExecuteScalar();
if (count > 0)
{
//You already inserted this ID. Warn the user
}
You are getting the exception on when inserting into table STUDENT
First, lets assume that the ID you are inserting into STUDENT that you're showing here is not the PRIMARY KEY of the table student, but only a FK (foreign key) to table PERSON.
In this case, the same fro the item 1 applies here. You ARE entering a duplicate id in the table. Use the same approach from item 1 to verify this.
But if the ID from PERSON is really the same ID from STUDENT (a ONE to ONE relationship), what's the problem?
Exactly the same. You are entering a duplicated ID.
So, no matter where the error is happening, you are allowing your code to try to insert a DUPLICATE ID (primary key) in the table.
Again, you must be creating the ID's manually, as an auto-increment primary key would not cause this problem (UNLESS you are manually setting the ID, in which case MySQL would use this value instead of the automatic value).
If you are creating the ID's manually, you MUST ensure that they are not duplicates.
I don't even know if this should be called an answer or a hack, but it worked:
string query = "INSERT INTO Person (ID, ...) VALUES(id, ...);
INSERT INTO Student (..., ID) VALUES(..., (select ID from Person WHERE Person.ID = id));";
MySqlCommand command = new MySqlCommand(query, connection);
This question already has answers here:
Cannot insert explicit value for identity column in table 'table' when IDENTITY_INSERT is set to OFF
(31 answers)
Closed 8 years ago.
I'm trying to insert data into fingerprint table which has four columns
- ID (primary key)
- StudentID (foreign key) linked to student table
- description
- Template
But the following error keeps coming up. I can't turn off the IDENTITY for ID as I want it to increment automatically. I also have a student table to store information. What I want to achieve is that after entering student details, I want to copy the studentID that was generated before onto the fingerprint table - StudentID column. the code I have for this is shown below.
private void btnSave_Click(object sender, EventArgs e)
{
fgrTemplate template = new fgrTemplate();
template.StudentID = std.StudentID;
template.Description = fngDes.Text;
template.Template = m_StoredTemplate;
if (upload.InsertTemplate(template))
{
MessageBox.Show("Student Successfully Added!");
}
else
{
MessageBox.Show("Student Not Successfully Added!");
}
using (SqlCommand com = new SqlCommand("INSERT INTO tblFingerprint (StudentID, Description, Template) values ('" + template.StudentID + "' ,'" + template.Description + "' ,#Template)", cn))
this is what I have on my web service. However it gives me the error
When issuing an INSERT statement for a table with an IDENTITY column, don't include the identity column in the fields and values list. For example, the following statement would fail:
INSERT INTO tbl (ID, StudentID) VALUES (1, 1)
but this statement will succeed:
INSERT INTO tbl (StudentID) VALUES (1)
and insert the next available identity value into the ID column.
Now, if you do want to insert an actual identity, do this:
SET IDENTITY_INSERT tbl ON
INSERT INTO tbl (ID, StudentID) VALUES (1, 1)
SET IDENTITY_INSERT tbl OFF
I’m hoping somebody will be able to help with my SQLite database problem.
I’m receiving a ConstraintException when querying my SQLite database with C#. The full exception message is “Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.” I originally built this database using access which worked fine, but for various reasons I had to recreate it using SQLite.
To give a bit of background - this is a simple status scheduling program. Each Status has an associated Account and Schedule. I realise Statuses and Schedule is a 1:1 relationship and could be in the same table but to allow the program to develop further I have split them into two tables.
See below for a cut down version of my table script (this is enough to recreate the problem).
PRAGMA foreign_keys = ON;
CREATE TABLE Accounts
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name char(100));
CREATE TABLE Statuses
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
AccountId INTEGER REFERENCES Accounts(ID) ON DELETE CASCADE,
Text char(140));
CREATE TABLE Schedule
(ID INTEGER PRIMARY KEY REFERENCES Statuses(ID) ON DELETE CASCADE,
StartDate char(255),
Frequency INT);
I did not have any issues until I created two Statues and associated them to the same Account.
Accounts
ID Name
1 Fred Blogs
Statuses
ID AccountId Text
1 1 “Some text”
2 1 “Some more text”
Schedule
ID StartDate Frequency
1 16/02/2011 1
2 16/02/2011 1
The select statement I’m using which throws the exception is:
SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
If I run the same query, but remove the ‘Accounts.Id’ column the query works fine.
See below for the C# code I’m using but I don’t think this is the problem
public DataTable Query(string commandText)
{
SQLiteConnection sqliteCon = new SQLiteConnection(ConnectionString);
SQLiteCommand sqliteCom = new SQLiteCommand(commandText, sqliteCon);
DataTable sqliteResult = new DataTable("Query Result");
try
{
sqliteCon.Open();
sqliteResult.Load(sqliteCom.ExecuteReader());
}
catch (Exception)
{
throw;
}
finally
{
sqliteCon.Close();
}
return sqliteResult;
}
Any help will be appreciated. Thanks.
the error is occuring due to the ID columns in Statuses table and Schedule table. If they are not important delete the columns from the two tables.
I have found a way round this problem. If I select the AccountId from the Schedule table rather than the Accounts table there is no exception thrown. It seems I was unable to run a SELECT statement that contained two Unique primary key columns.
So instead of
SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
I run
SELECT Statuses.Id, Statuses.Text, Statuses.AccountId, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
I fixed the issue by reading the schema only at first, then cleared the constraints of the datatable and then read again the data.
like this :
DataSet DS = new DataSet();
mytable = new DataTable();
DS.Tables.Add(mytable);
DS.EnforceConstraints = false;
SQLiteCommand command = DBconnection.CreateCommand();
command.CommandText = "select * from V_FullView";
SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly);
mytable.Load(reader);
mytable.Constraints.Clear();
reader = command.ExecuteReader();
mytable.Load(reader);
reader.Close();
my V_FullView is a view of 4 different tables merged. It seems that the constraints are the ones of the first merged table (name was unique on that one, but replicated a multiple of times in the view)