DbUnit: insert data into DB2 database after turning of foreign keys - database

I'm trying to insert initial data into a DB2 database in DbUnit using DatabaseOperation.INSERT.execute(...) which works fine with some datasets. In order to insert some datasets however, I need to disable foreign key constraints first (because the tables in some datasets can be listed in a 'wrong' order).
I'm disabling the foreign key constraints with command SET INTEGRITY FOR <table_name> OFF, but when I try to insert the data after calling that command, I get this error:
com.ibm.db2.jcc.am.SqlException: DB2 SQL Error: SQLCODE=-668, SQLSTATE=57016, SQLERRMC=1;SCHEMA.TABLE, DRIVER=4.17.30
The IBM error code explanation isn't much helpfull here. Is there something I need to do after setting integrity on a table and before inserting data into that table?
EDIT:
I found this in the documentation for the OFF statement: "Specifies that the tables are placed in set integrity pending state. Only very limited activity is allowed on a table that is in set integrity pending state."
If I understand it correctly, this means that when I turn off the integrity checks on a table, I cannot perform any write/modify operations on it! What's the point of turning the integrity check off then? I need to find a way to do this.

You are not "disabling the foreign key constraints with command SET INTEGRITY". SET INTEGRITY OFF basically means "I'm not sure about the integrity of this table data, so I'd rather restrict access to it until I figure out what's wrong".
To temporary disable foreign key verification you might try ALTER TABLE foo ALTER FOREIGN KEY bar NOT ENFORCED.

Related

How to make constraints work in Snowflake?

Is there a way for constraints to actually work in Snowflake?
A primary key is created. Still duplicates can be inserted in the table. Giving options like cascade update and delete cascade are not working with Foreign key
Can someone please help?
if you read the Snowflake documentation you will see that only NOT NULL constraints are enforced, all other constraint types are informational only.
I am guessing that the reason for this is that Snowflake is an analytical, rather than an OLTP, database and therefore the expectation is that constraints are enforced in your ELT processes (as is normal practice) rather than in the DB.
Snowflake does not enforce constraints except not null.
Snowflake Notes . I think we cannot enforce a constraint in snowflake database but you can apply the constraint in your ETL tool(if using)

When/how are Constraints Checked in a SqlBulkCopy w/ Check Constraints enabled?

I am performing several SqlBulkCopy's in a single transaction, I need to be able to roll back easily if anything goes wrong. I'm bulk copying several tables that have foreign keys to each other. I want these constraints checked. I'm copying the parent table first, then the child tables, but I'm receiving foreign key constraint errors. Does SqlBulkCopy include the rows inserted in the transaction when checking constraints?
By default constraints are not checked. Change the options of the SqlBulkCopy to check them during insertion.
Check constraints while data is being inserted. By default,
constraints are not checked

Different behavior in 2 SQL servers

I have a project that run some integration tests. The project creates a new database each time and run the tests against this new db. Recently I moved this project to a new server and I'm having some issues when delete data from the db.
I execute the following query:
DELETE FROM TABLE1;
DELETE FROM TABLE2;
DELETE FROM TABLE3;
On the server A everything works as expected, however using server B I'm getting the following error:
The DELETE statement conflicted with the REFERENCE constraint
"FK_....". The conflict occurred in database
"TestDB", table "Table1", column
'...'.
Both servers have the same version of SQL server
Microsoft SQL Server 2012 (SP1) - 11.0.3401.0 (X64)
Jan 9 2014 13:22:15
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)
Both Schema and data are the same and DB are created using the same process.
Any Ideas?
Actually, it is possible to have the same schema in both places, and even the same data, and experience different behavior. How? Because constraints (CHECK and FOREIGN KEY) can be disabled. Yup.
To see if the Foreign Key in question is enabled or disabled, just run the the following, making sure to put the name of the FK in question in the WHERE clause:
SELECT *
FROM sys.foreign_keys
WHERE [name] = N'{name_of_FK_in_question}';
Look at the column named is_disabled. I suspect that it is set to 1 on Server A (where everything "works") and is 0 on Server B (where things "don't work"). I put "works" and "don't work" in quotes, because if this is truly the case, then reality is the opposite of what you are experiencing. Meaning, the system with the FK enabled and getting the error is actually working as that is what FKs should do. The system not getting an error is possibly allowing orphaned (i.e. bad) data in.
To enable the FK, run the following:
ALTER TABLE {table_name}
WITH CHECK -- verifies the data currently in the table
CHECK CONSTRAINT [{name_of_FK_in_question}];
Of course, if the bad data is there, you either need to:
Delete the bad data first, or
Specify WITH NOCHECK on the ALTER so that it will accept the bad data:
ALTER TABLE {table_name}
WITH NOCHECK -- accept the bad data aleady there
CHECK CONSTRAINT [{name_of_FK_in_question}];
However, this does not solve the issue 100%. If you run that SELECT query (noted above) again, you should see that the is_disabled field is now set to 0. BUT, if you look at the is_not_trusted field, it will be set to 1. If a constraint is enabled yet not trusted, it will enforce its rule as expected, but the Query Optimizer (Q.O.) will ignore it, which is generally not a great thing as the constraints are actually used not just to enforce data integrity rules, but also as clues for the Q.O. to logically reduce certain steps in some queries (i.e. they sometimes help increase performance). In order to get the constraint to be "trusted", you will have to delete the bad data and verify all constraints on the table via:
ALTER TABLE {table_name}
WITH CHECK -- verifies the data currently in the table
CHECK CONSTRAINT [{name_of_FK_in_question}];
However, if for some reason you need the "bad" data, then you will just have a Foreign Key that enforces data integrity but has no potential for improving performance (which is still much better than having no FK defined :).
For more info, please see the MSDN page for ALTER TABLE.
For the sake of completeness I will also mention that it is possible that on Server A (where there is no error), that the FK is defined with the option ON DELETE CASCADE which auto-deletes and related data prior to removing the row(s) from the table that is being deleted from, while Server B (where there is an error) does not have the ON DELETE action specfied (or is specified as NO ACTION). This, however, is something that should show up when doing a schema compare (unless specifying to ignore the ON DELETE and ON UPDATE actions), whereas whether the constraint is enabled or disabled is more likely to be ignored in a schema compare.
There is a foreign key (named in the error message) which is preventing you from deleting an item from Table1 because it would violate the foreign key (i.e. a there would be a row in the other table which referenced the row that you were about to delete)
The difference between the two databases is going to either be:
The first database didn't have the foreign key
The first database didn't have any rows in the table constrained by the foreign key
To find which table the foreign key is on see the question How can I list all foreign keys referencing a given table in SQL Server?
EXEC sp_fkeys 'TableName'
Like Justin says, either the keys or data isn't the same, if it works for your case, then setting the keys to cascade of delete will remedy this, but you must identify the keys first.

Can't work around this foreign key constraint rule using TRIGGER in SQLite?

First, I want to talk a little about the Foreign key constraint rule and how helpful it is. Suppose I have two tables, a primary table with the primary column called ID, the other table is the foreign one which also has a primary column called ID. This column in the foreign table refers to the ID column in the primary table. If we don't establish any Foreign key relation/constraint between those tables, we may fall foul of many problems related to integrity.
If we create the foreign key relation for them, any changes to the ID column in primary table will 'auto' reflect to the ID column in the foreign table, changes here can be made by DELETE, UPDATE queries. Moreover, any changes to the ID in the foreign table should be constrained by the ID column in the primary table, for example there shouldn't any new value inserted or updated in the ID column of the foreign table unless it does exist in the ID column of the primary table.
I know that SQLite doesn't support foreign key constraint (with full functions as detailed above) and I have to use TRIGGER to work around this problem. I have used TRIGGER to work around successfully in one way (Any changes to the ID column in the primary table will refect to the ID column in the foreign table) but the reverse way (should throw/raise any error if there is a confict occurs, for example, there are only values 1,2,3 in the ID column of the primary table, but the value 2 in the ID column of the foreign table is updated to 4 -> not exist in the primary table -> should throw error) is not easy. The difficult is SQLite doesn't also support IF statement and RAISERROR function. If these features were supported, I could work around easily.
I wonder how you can use SQLite if it doesn't support some important features? Even working around by using TRIGGER is not easy and I think it's impossible, except that you don't care about the reverse way. (In fact, the reverse way is not really necessary if you set up your SQL queries carefully, but who can make sure? Raising error is a mechanism reminding us to fix and correct and making it work exactly without corrupting data and the bugs can't be invisible.
If you still don't know what I want, I would like to have some last words, my purpose is to achieve the full functionality of the Foreign key constraint which is not supported in SQLite (even you can create such a relationship but it's fake, not real as you can benefit from it in SQL Server, SQL Server Ce, MS Access or MySQL).
Your help would be highly appreciated.
PS: I really like SQLite because it is file-based, easy to deploy, supports large file size (an advantage over SQL Server Ce) but some missing features have made me re-think many times, I'm afraid if going for it, my application may be unreliable and corrupt unpredictably.
To answer the question that you have skillfully hidden in your rant:
SQLite allows the RAISE function inside triggers; because of the lack of control flow statements, this must be used with a SELECT:
CREATE TRIGGER check_that_id_exists_in_parent
BEFORE UPDATE OF id ON child_table
FOR EACH ROW
BEGIN
SELECT RAISE(ABORT, 'parent ID does not exist')
WHERE NOT EXISTS (SELECT 1
FROM parent_table
WHERE id = NEW.id);
END;

How can we make foreign key among tables after inserting data in those tables?

I have created tables in sql server. And i have also inserted data/rows in that tables.
Now i want to make relationship among them means i want to create foreign key constraints among them, is it possible ?
Whenever i try to create relationship among table a problem is occured. "Saving changes is permitted, The changes you made required table to re-created and dropped"
Please suggest me what should i do to make relationship(foreign key) among them ?
My Child table design is this
this is my parent table:-
please now right what alter query i should write..?
You can try this link
"Error message when you try to save a table in SQL Server 2008: "Saving changes is not permitted"
Another solution is below.
I think the problem is because of a feature when using the GUI. If you have a look at this link it shows you how to work round it. It is a feature which prevents you from dropping and recreating the table which is what SSMS does in the background when you click ok.
The code provided by the previous posted is the best way to do this.
You could do this with a script like this:
alter table ChildTable
add constraint FK_ChildTable_ColumnName foreign key (ColumnName) references ParentTable(PrimaryKeyColumnName)
[Edit] If I read your description correctly the script would be:
alter table emp
add constraint FK_emp_salary foreign key(salary) references testing(roll)
You can only add foreign constraints that aren't violated by existing data. You may also have to add suitable indices first, although this depends on the DBMS. In any case, first make sure your existing data is compatible with the foreign keys you want to introduce. In other words, if you were to create the foreign key first, and then insert the data, you should not produce any foreign key violations.

Resources