Rollback data liquibase.exception.RollbackFailedException: liquibase.exception.DatabaseException: Referential integrity constraint violation: - liquibase

I try to roll back data after test runnining using:
delete from instance;
delete from workspace;
however I receive:
liquibase.exception.RollbackFailedException: liquibase.exception.DatabaseException: Referential integrity constraint violation:
"FK_INSTANCE_ID: PUBLIC.WORKSPACE FOREIGN KEY(INSTANCE_ID) REFERENCES PUBLIC.INSTANCE(ID) (1)"; SQL statement:
I figured out that it is caused by required relation beetween tables. How to force deletion.

You don't specify what database platform you are using, and the answer might differ depending on that. In general though, you need to either use a 'cascade' with delete, or else delete the relationships before deleting the tables.

Related

deleteAll doesn't work with foreign keys to other rows in same table

I have a Model class that has an attribute referencing another instance of the same Model class. Its basically a tree structure in one Model.
When I try to exectute MyModel.deleteAll() it fails because a foreign key constraint fails.
Is there someway to easily suspend this constraint for the deleteAll query?
The only workaround I've found, since I'm using mysql, is to issue a TRUNCATE statement, which mysql accepts straight away.
Thanks in advance,
Evan
Exception details:
org.javalite.activejdbc.DBException: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (visibledb_testing.accountabilities, CONSTRAINT accountabilities_prototype_id FOREIGN KEY (prototype_id) REFERENCES accountabilities (id)), query: DELETE FROM accountabilities
The Model#deleteAll() simply generates SQL DELETE FROM YOURTABLE.
If you can run this on MySQL console, it will work from the model. If you are getting constraint violation, maybe you want to:
Base.exec("TRUNCATE " + MyModel.getTableName());
Alternatively, you can try http://javalite.io/delete_cascade#method-deletecascade. BE CAREFUL- this is a powerful but dangerous method, only use after reading all docs.

Adding foreign key fails unless data is first removed and reinserted after

I have an odd issue with foreign keys. I am trying to perform the following query:
ALTER TABLE [GroupMember] FOREIGN KEY ([Group]) REFERENCES [Group]([GUID])
Which gives me the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__GroupMember__Group__0D25C822". The conflict occurred in database "x", table "dbo.Group", column 'GUID'.
I then verified the existing things, which I have confirmed are all ok:
Referenced table (dbo.Group) has a defined PRIMARY KEY on [GUID] column
Referencing table (dbo.GroupMember) has no [Group]-values which do not exist in [GUID]-column of dbo.Group-table
No similarly referencing foreign keys exist already
From here on, I experimented. Taking some rows in and out, wiping the table, truncating the table. What I can conclude so far:
If I wipe the referencing table using DELETE FROM [GroupMember]; then try to apply the FK constraint, I receive the same error message
If I truncate the referencing table using TRUNCATE TABLE [GroupMember];, I can apply the FK constraint without errors. Additionally, I am able to reinsert the exact same data after applying the FK constraint, without problems.
From this I can conclude that the data itself is not the problem. Can anyone make sense of this? Why am I able to apply the constraint after truncating the table, but not after deleting all records?
If you are using Microsoft SSMS check whether unchecking "Prevent saving changes that require table re-creation" solves the problem. You'll find this in Options > Designers > Table and Database Designers.
I have had similar issues that have been resolved by this. Let me know if it works or not.
Good luck.

Add Foreign Key Contraint between Tables in different Databases [duplicate]

I have two tables in two different databases. In table1 (in database1) there is a column called column1 and it is a primary key. Now in table2 (in database2) there is a column called column2 and I want to add it as a foreign key.
I tried to add it and it gave me the following error:
Msg 1763, Level 16, State 0, Line 1
Cross-database foreign key references are not supported. Foreign key Database2.table2.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.
How do I do that since the tables are in different databases.
You would need to manage the referential constraint across databases using a Trigger.
Basically you create an insert, update trigger to verify the existence of the Key in the Primary key table. If the key does not exist then revert the insert or update and then handle the exception.
Example:
Create Trigger dbo.MyTableTrigger ON dbo.MyTable, After Insert, Update
As
Begin
If NOT Exists(select PK from OtherDB.dbo.TableName where PK in (Select FK from inserted) BEGIN
-- Handle the Referential Error Here
END
END
Edited: Just to clarify. This is not the best approach with enforcing referential integrity. Ideally you would want both tables in the same db but if that is not possible. Then the above is a potential work around for you.
If you need rock solid integrity, have both tables in one database, and use an FK constraint. If your parent table is in another database, nothing prevents anyone from restoring that parent database from an old backup, and then you have orphans.
This is why FK between databases is not supported.
You could use check constraint with a user defined function to make the check. It is more reliable than a trigger. It can be disabled and reenabled when necessary same as foreign keys and rechecked after a database2 restore.
CREATE FUNCTION dbo.fn_db2_schema2_tb_A
(#column1 INT)
RETURNS BIT
AS
BEGIN
DECLARE #exists bit = 0
IF EXISTS (
SELECT TOP 1 1 FROM DB2.SCHEMA2.tb_A
WHERE COLUMN_KEY_1 = #COLUMN1
) BEGIN
SET #exists = 1
END;
RETURN #exists
END
GO
ALTER TABLE db1.schema1.tb_S
ADD CONSTRAINT CHK_S_key_col1_in_db2_schema2_tb_A
CHECK(dbo.fn_db2_schema2_tb_A(key_col1) = 1)
In my experience, the best way to handle this when the primary authoritative source of information for two tables which are related has to be in two separate databases is to sync a copy of the table from the primary location to the secondary location (using T-SQL or SSIS with appropriate error checking - you cannot truncate and repopulate a table while it has a foreign key reference, so there are a few ways to skin the cat on the table updating).
Then add a traditional FK relationship in the second location to the table which is effectively a read-only copy.
You can use a trigger or scheduled job in the primary location to keep the copy updated.
The short answer is that SQL Server (as of SQL 2008) does not support cross database foreign keys--as the error message states.
While you cannot have declarative referential integrity (the FK), you can reach the same goal using triggers. It's a bit less reliable, because the logic you write may have bugs, but it will get you there just the same.
See the SQL docs # http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx Which state:
Triggers are often used for enforcing
business rules and data integrity. SQL
Server provides declarative
referential integrity (DRI) through
the table creation statements (ALTER
TABLE and CREATE TABLE); however, DRI
does not provide cross-database
referential integrity. To enforce
referential integrity (rules about the
relationships between the primary and
foreign keys of tables), use primary
and foreign key constraints (the
PRIMARY KEY and FOREIGN KEY keywords
of ALTER TABLE and CREATE TABLE). If
constraints exist on the trigger
table, they are checked after the
INSTEAD OF trigger execution and prior
to the AFTER trigger execution. If the
constraints are violated, the INSTEAD
OF trigger actions are rolled back and
the AFTER trigger is not executed
(fired).
There is also an OK discussion over at SQLTeam - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135
Achieving referential integrity accross databases is not an easy task.
Here is a list of frequently employed mechanisms:
Clone & Sync: The referenced data is regularly cloned/merged into the referencing database. This may be suitable if the referenced data is rarely changing. You end up with two physical copies of the same data, and need a reliable process to keep them in sync (e.g. with an ETL pipeline).
Triggers: Changes to the referencing data and the referenced data are caught by SQL triggers, which ensure referential integrity. However, triggers can be slow, and may not fire at a database restore. It cannot hurt to run scheduled consistency checks as part of the operations monitoring. Write access to the referenced database is required for installing and maintaining the trigger.
Check constraints: SQL-Server offers user-defined contraints, which ensure that every row satisfies a given condition. One can exploit this functionality by writing a user defined function that checks the existence of a row in the referenced data, and then use this function as a CHECK's predicate in the referencing table. This does not catch changes in the referenced data. It is an RDBMS-specific solution, but works accross server boundaries (e.g. using linked servers). It is a good choice for referencing globally unique IDs, such as article codes in a company's ERP system, which never get deleted or re-assigned.
Re-think database architecture: When all the above mechanisms are unsatisfactory, multiple databases may be merged in a single database. The originating database names can become schema names, allowing effective grouping of database objects.
As the error message says, this is not supported on sql server.
The only way to ensure refrerential integrity is to work with triggers.

Create constraint alter table invalid

I had to modify an existing constraint so it would cascade updates and deletes.
To do this I first removed the constraint and was planning on adding it (through an ALTER TABLE) but this fails.
When I commit the query below it gives me the error 'ORA-01735: invalid ALTER TABLE option':
ALTER TABLE
PARAM
ADD CONSTRAINT
FK_PARAM_PORTLET FOREIGN KEY (PORTLETID)
REFERENCES PORTLET(ID)
ON DELETE CASCADE ON UPDATE CASCADE;
Any idea what it could be? Am I overlooking something?
Oracle does not support ON UPDATE CASCADE in foreign keys.
Have a look at this question for tips: How to create a Foreign Key with "ON UPDATE CASCADE" on Oracle?
UPDATE CASCADE is not supported in Oracle. You will need to manage this via triggers.
Check Oracle statement:
Referential integrity constraints can specify particular actions to be
performed on the dependent rows in a child table if a referenced
parent key value is modified. The referential actions supported by the
FOREIGN KEY integrity constraints of Oracle are UPDATE and DELETE NO
ACTION, and DELETE CASCADE.

Add Foreign Key relationship between two Databases

I have two tables in two different databases. In table1 (in database1) there is a column called column1 and it is a primary key. Now in table2 (in database2) there is a column called column2 and I want to add it as a foreign key.
I tried to add it and it gave me the following error:
Msg 1763, Level 16, State 0, Line 1
Cross-database foreign key references are not supported. Foreign key Database2.table2.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint. See previous errors.
How do I do that since the tables are in different databases.
You would need to manage the referential constraint across databases using a Trigger.
Basically you create an insert, update trigger to verify the existence of the Key in the Primary key table. If the key does not exist then revert the insert or update and then handle the exception.
Example:
Create Trigger dbo.MyTableTrigger ON dbo.MyTable, After Insert, Update
As
Begin
If NOT Exists(select PK from OtherDB.dbo.TableName where PK in (Select FK from inserted) BEGIN
-- Handle the Referential Error Here
END
END
Edited: Just to clarify. This is not the best approach with enforcing referential integrity. Ideally you would want both tables in the same db but if that is not possible. Then the above is a potential work around for you.
If you need rock solid integrity, have both tables in one database, and use an FK constraint. If your parent table is in another database, nothing prevents anyone from restoring that parent database from an old backup, and then you have orphans.
This is why FK between databases is not supported.
You could use check constraint with a user defined function to make the check. It is more reliable than a trigger. It can be disabled and reenabled when necessary same as foreign keys and rechecked after a database2 restore.
CREATE FUNCTION dbo.fn_db2_schema2_tb_A
(#column1 INT)
RETURNS BIT
AS
BEGIN
DECLARE #exists bit = 0
IF EXISTS (
SELECT TOP 1 1 FROM DB2.SCHEMA2.tb_A
WHERE COLUMN_KEY_1 = #COLUMN1
) BEGIN
SET #exists = 1
END;
RETURN #exists
END
GO
ALTER TABLE db1.schema1.tb_S
ADD CONSTRAINT CHK_S_key_col1_in_db2_schema2_tb_A
CHECK(dbo.fn_db2_schema2_tb_A(key_col1) = 1)
In my experience, the best way to handle this when the primary authoritative source of information for two tables which are related has to be in two separate databases is to sync a copy of the table from the primary location to the secondary location (using T-SQL or SSIS with appropriate error checking - you cannot truncate and repopulate a table while it has a foreign key reference, so there are a few ways to skin the cat on the table updating).
Then add a traditional FK relationship in the second location to the table which is effectively a read-only copy.
You can use a trigger or scheduled job in the primary location to keep the copy updated.
The short answer is that SQL Server (as of SQL 2008) does not support cross database foreign keys--as the error message states.
While you cannot have declarative referential integrity (the FK), you can reach the same goal using triggers. It's a bit less reliable, because the logic you write may have bugs, but it will get you there just the same.
See the SQL docs # http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx Which state:
Triggers are often used for enforcing
business rules and data integrity. SQL
Server provides declarative
referential integrity (DRI) through
the table creation statements (ALTER
TABLE and CREATE TABLE); however, DRI
does not provide cross-database
referential integrity. To enforce
referential integrity (rules about the
relationships between the primary and
foreign keys of tables), use primary
and foreign key constraints (the
PRIMARY KEY and FOREIGN KEY keywords
of ALTER TABLE and CREATE TABLE). If
constraints exist on the trigger
table, they are checked after the
INSTEAD OF trigger execution and prior
to the AFTER trigger execution. If the
constraints are violated, the INSTEAD
OF trigger actions are rolled back and
the AFTER trigger is not executed
(fired).
There is also an OK discussion over at SQLTeam - http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=31135
Achieving referential integrity accross databases is not an easy task.
Here is a list of frequently employed mechanisms:
Clone & Sync: The referenced data is regularly cloned/merged into the referencing database. This may be suitable if the referenced data is rarely changing. You end up with two physical copies of the same data, and need a reliable process to keep them in sync (e.g. with an ETL pipeline).
Triggers: Changes to the referencing data and the referenced data are caught by SQL triggers, which ensure referential integrity. However, triggers can be slow, and may not fire at a database restore. It cannot hurt to run scheduled consistency checks as part of the operations monitoring. Write access to the referenced database is required for installing and maintaining the trigger.
Check constraints: SQL-Server offers user-defined contraints, which ensure that every row satisfies a given condition. One can exploit this functionality by writing a user defined function that checks the existence of a row in the referenced data, and then use this function as a CHECK's predicate in the referencing table. This does not catch changes in the referenced data. It is an RDBMS-specific solution, but works accross server boundaries (e.g. using linked servers). It is a good choice for referencing globally unique IDs, such as article codes in a company's ERP system, which never get deleted or re-assigned.
Re-think database architecture: When all the above mechanisms are unsatisfactory, multiple databases may be merged in a single database. The originating database names can become schema names, allowing effective grouping of database objects.
As the error message says, this is not supported on sql server.
The only way to ensure refrerential integrity is to work with triggers.