This question already has answers here:
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints
(26 answers)
Closed 8 years ago.
I have this query running against 2008R2. tblJoin is the table in between two tables(tblIncident and tblPatron) for many-to-many relationship.
While I am building the query in VS2012, in the Query Builder window when I execute the query it runs fine and gives me the desired results. However in the last step when I click on TestQuery and enter the parameter it gives an error:
"Failed to enable constraints.."
I checked the datatype and they all match against each other against the tables,
SELECT tblIncident.Inci_ID,
_tblJoin.PatronID,
_tblJoin.LName,
_tblJoin.FName,
_tblJoin.MI
FROM tblJoin INNER JOIN
tblIncident ON tblJoin.InciID = tblIncident.Inci_ID AND tblJoin.InciID = tblIncident.Inci_ID
WHERE (tblIncident.Inci_ID = #Inci_ID)
You need Check all the MaxLength property of the columns in your DataTable.
The column that I changed from "nvarchar(512)" to "nvarchar(MAX)" still had the 512 value on the MaxLength property so I changed to "-1" and it works!!.
You can solve this issue from this discussion
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints
There have many answers ....
Thanks Ramesh and Vignesh. Vignesh's comment made me think about the duplicate foreign key. So I kept the query but removed the foreign key (Incident ID), that made it worked. This is how my query looks like:
SELECT tblJoin.PatronID, tblJoin.LName, tblJoin.FName, tblJoin.MI FROM tblJoin
INNER JOIN tblIncident ON tblJoin.InciID = tblIncident.Inci_ID
WHERE (tblIncident.Inci_ID = #Inci_ID)
Related
This question already has answers here:
How to set unique constraint over multiple columns when any one can be null?
(3 answers)
Closed 4 months ago.
I have a unique constraint on one of my tables:
CREATE UNIQUE INDEX `role_contextid_targetid_ownerid_type_endedat_unique` on `role` (`contextId`, `targetId`, `ownerId`, `type`, `endedAt`)
You can see it is part of the db definition here:
But for some reason it is still allowing multiple entries which share all of their contextId, targetId, ownerId, type, endedAt values. Notice the last three items below:
Am I misunderstanding what a multi-column unique index is supposed to do? In not, why did SQLite allow me to add items that break these rules?
Here's what docs are saying
For the purposes of unique indices, all NULL values are considered different from all other NULL values and are thus unique.
So, it considers NULLS as different values which makes all the problem lines unique from the DB's point of view
dbfiddle
I have a query like this (simplified and anonymised):
SELECT
Department.id,
Department.name,
Department.manager_id,
Employee.name AS manager_name
FROM
Department
LEFT OUTER JOIN Employee
ON Department.manager_id = Employee.id;
The field Department.manager_id may be NULL. If it is non-NULL then it is guaranteed to be a valid id for precisely one row in the Employee table, so the OUTER JOIN is there just for the rows in the Department table where it is NULL.
Here is the problem: old instances of the database do not have this Department.manager_id column at all. In those cases, I would like the query to act as if the field did exist but was always NULL, so e.g. the manager_name field is returned as NULL. If the query only used the Department table then I could just use SELECT * and check for the column in my application, but the JOIN seems to make this impossible. I would prefer not to modify the database, partly so that I can load the database in read only mode. Can this be done just by clever adjustment of the query?
For completeness, here is an answer that does not require munging both possible schemas into one query (but still doesn't need you to actually do the schema migration):
Check for the schema version, and use that to determine which SELECT query to issue (i.e. with or without the manager_id column and JOIN) as a separate step. Here are a few possibilities to determine the schema version:
The ideal situation is that you already keep track of the schema by assigning version numbers to the schema and recording them in the database. Commonly this is done with either:
The user_version pragma.
A table called "Schema" or similar with one row containing the schema version number.
You can directly determine whether the column is present in the table. Two possibilities:
Use the table_info pragma to determine the list of columns in the table.
Use a simple SELECT * FROM Table LIMIT 1 and look at what columns are returned (this is probably better as it is independent of the database engine).
This seems to work:
SELECT
Dept.id,
Dept.name,
Dept.manager_id,
Employee.name AS manager_name
FROM
(SELECT *, NULL AS manager_id FROM Department) AS Dept
LEFT OUTER JOIN Employee
ON Dept.manager_id = Employee.id;
If the manager_id column is present in Department then it is used for the join, whereas if it is not then Dept.manager_id and Employee.name are both NULL.
If I swap the column order in the subquery:
(SELECT NULL AS manager_id, * FROM Department) AS Dept
then the Dept.manager_id and Employee.name are both NULL even if the Department.manager_id column exists, so it seems that Dept.manager_id refers to the first column in the Dept subquery that has that name. It would be good to find a reference in the SQLite documentation saying that this behaviour is guaranteed (or explicitly saying that it is not), but I can't find anything (e.g. in the SELECT or expression pages).
I haven't tried this with other database systems so I don't know if it will work with anything other than SQLite.
I am currently working on a database structure in SQLite Studio (not sure whether that's in itself important, but might as well mention), and error messages are making me wonder whether I'm just going at it the wrong way or there's some subtlety I'm missing.
Assume two tables, people-basics (person-ID, person-NAME, person-GENDER) and people-stats (person-ID, person-NAME, person-SIZE). What I'm looking into achieving is "Every record in people-basics corresponds to a single record in people-stats.", ideally with the added property that person-ID and person-NAME in people-stats reflect the associated person-ID and person-NAME in people-basics.
I've been assuming up to now that one would achieve this with Foreign Keys, but I've also been unable to get this to work.
When I add a person in people-basics, it works fine, but then when I go over to people-stats no corresponding record exists and if I try to create one and fill the Foreign Key column with corresponding data, I get this message: "Cannot edit this cell. Details: Error while executing SQL query on database 'People': no such column: people-basics.person" (I think the message is truncated).
The DDL I currently have for my tables (auto-generated by SQLite Studio based on my GUI operations):
CREATE TABLE [people-basics] (
[person-ID] INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE
NOT NULL,
[person-NAME] TEXT UNIQUE
NOT NULL,
[person-GENDER] TEXT
);
CREATE TABLE [people-stats] (
[person-NAME] TEXT REFERENCES [people-basics] ([person-NAME]),
[person-SIZE] NUMERIC
);
(I've removed the person-ID column from people-stats for now as it seemed like I should only have one foreign key at a time, not sure whether that's true.)
Alright, that was a little silly.
The entire problem was solved by removing hyphens from table names and column names. (So: charBasics instead of char-basics, etc.)
Ah well.
This question already has an answer here:
Error when trying to update sqlite database in android
(1 answer)
Closed 6 years ago.
Working with the artist/tracks example at https://www.sqlite.org/foreignkeys.html
I'd like to drop both tables. I would think that if I first drop tracks (which References artist) I could then drop artists:
stat_5.executeUpdate("drop table if exists tracks;");
stat_6.executeUpdate("drop table if exists artist;");
But this issues an exception "SQLException: foreign key constraint failed"
What am I missing?
The documentation says:
If foreign key constraints are enabled, a DROP TABLE command performs an implicit DELETE FROM command before removing the table from the database schema. [...] If the implicit DELETE FROM executed as part of a DROP TABLE command violates any immediate foreign key constraints, an error is returned and the table is not dropped.
Remove the data in the correct order so that all intermediate steps are valid.
Or just disable foreign constraint checking.
I'm working with SQLite in Flash.
I have this unique index:
CREATE UNIQUE INDEX songsIndex ON songs ( DiscID, Artist, Title )
I have a parametised recursive function set up to insert any new rows (single or multiple).
It works fine if I try to insert a row with the same DiscID, Artist and Title as an existing row - ie it ignores inserting the existing row, and tells me that 0 out of 1 records were updated - GOOD.
However, if, for example the DiscId is blank, but the artist and title are not, a new record is created when there is already one with a blank DiscId and the same artist and title - BAD.
I traced out the disc id prior to the insert, and Flash is telling me it's undefined. So I've coded it to set anything undefined to "" (an empty string) to make sure it's truly an empty string being inserted - but subsequent inserts still ignore the unique index and add a brand new row even though the same row exists.
What am I misunderstanding?
Thanks for your time and help.
SQLite allows NULLable fields to participate in UNIQUE indexes. If you have such an index, and if you add records such that two of the three columns have identical values and the other column is NULL in both records, SQLite will allow that, matching the behavior you're seeing.
Therefore the most likely explanation is that despite your effort to INSERT zero-length strings, you're actually still INSERTing NULLs.
Also, unless you've explicitly included OR IGNORE in your INSERT statements, the expected behavior of SQLite is to throw an error when you attempt to insert a duplicate INDEX value into a UNIQUE INDEX. Since you're not seeing that behavior, I'm guessing that Flash provides some kind of wrapper around SQLite that's hiding the true behavior from you (and could also be translating empty strings to NULL).
Larry's answer is great. To anyone having the same problem here's the SQLite docs citation explaining that in this case all NULLs are treated as different values:
For the purposes of unique indices, all NULL values are considered
different from all other NULL values and are thus unique. This is one
of the two possible interpretations of the SQL-92 standard (the
language in the standard is ambiguous). The interpretation used by
SQLite is the same and is the interpretation followed by PostgreSQL,
MySQL, Firebird, and Oracle. Informix and Microsoft SQL Server follow
the other interpretation of the standard, which is that all NULL
values are equal to one another.
See here: https://www.sqlite.org/lang_createindex.html