Disable foreign key constraint on all tables didn't work - sql

I try a lot of commands to disable tables constraints in my database to make truncate to all tables but still now it give me the same error:
Cannot truncate table '' because it is being referenced by a FOREIGN KEY constraint.
I try
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
EXEC sp_MSforeachtable "TRUNCATE TABLE ?"
And I tried this for each table
ALTER TABLE [Table Name] NOCHECK CONSTRAINT ALL
truncate table [Table Name]
ALTER TABLE [Table Name] CHECK CONSTRAINT ALL
and every time I have the previous error message. How can I solve this problem?

If you want to truncate the table, probably you have to drop the foreign keys and add them back. From here.
"You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint; instead, use DELETE statement without a WHERE clause. Because TRUNCATE TABLE is not logged, it cannot activate a trigger."
Similar question here in SO.

I think is a rather bad idea. It isn't a good idea to blindly run those sort of SQL commands on ALL tables in your database.
What exactly are you trying to do?
If you want to create a copy of your Database (for example) with the same tables, with no data in them you can do that with SSIS package very easily (just make sure the COPY DATA) option is set to False
http://www.kodyaz.com/articles/transfer-sql-server-objects-task.aspx

Related

How to add check constraint on a column in table?

ALTER TABLE Student ADD CONSTRAINT CHK_Student_ID_LENGTH CHECK (LEN([ID]) between 12 and 14);
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME = 'CHK_Student_ID_LENGTH';
alter table Student drop constraint CHK_Student_ID_LENGTH;
I tried to add check constraint using the first statement. It gave me the below error.
[23000][547] The ALTER TABLE statement conflicted with the CHECK constraint "CHK_Student_ID_LENGTH". The conflict occurred in database, table "Student", column 'ID'.
I tried to check if there was any existing constraint with the same name. But I did not get any. Still I tried to drop the constraint. But then it gave the error:
CHK_Student_ID_LENGTH is not a constraint.
But still add constraint statement gives error saying it already exists. Where am I going wrong?
The error message is a little badly worded, but isn't saying what you think it's saying.
It's not saying that there's already a constraint with the same name. It's saying that the constraint is being violated. That means that there is data already in the table that doesn't meet the requirements of the new constraint you're trying to introduce.
You could use the NOCHECK option to create the constraint whilst allowing existing data to violate it. But this is frequently the wrong thing to do. It is usually more sensible to fix the existing data.
Specifying NOCHECK means that the constraint can't be used by the optimizer to eliminate redundant actions that the logic of the constraint would preclude.
You probably have some records in Your table that conflict with that new constraint.
Just find them and UPDATE/DELETE before adding a contraint.
SELECT *
FROM Student
WHERE LEN([ID]) between 12 and 14
Or try to add that constraint without checking existing values using WITH NOCHECK
ALTER TABLE Student WITH NOCHECK
ADD CONSTRAINT CHK_Student_ID_LENGTH CHECK (LEN([ID]) between 12 and 14);
Tip: In migration files I usually add this before adding a new constraint:
IF OBJECT_ID('CHK_Student_ID_LENGTH') IS NOT NULL
ALTER TABLE Student DROP CONSTRAINT CHK_Student_ID_LENGTH
IF OBJECT_ID('CHK_Student_ID_LENGTH') IS NULL
ALTER TABLE Student ADD CONSTRAINT ...
More about ALTER TABLE https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql?view=sql-server-ver15

SQL Primary Key Exception

I have a Mircrosoft Sql Server database made up of about 8 tables that are all related that I am trying to update. To do this I create a number of temporary tables
"CREATE TABLE [vehicle_data].[dbo].[temp_MAINTENANCE_EVENT] (" +
"[maintenance_event_id] int," +
"[maintenance_computer_code_id] int," +
"[veh_eng_maintenance_id] int," +
"CONSTRAINT [PK_maintenance_event_id"] PRIMARY KEY CLUSTERED ([maintenance_event_id] ASC))";
Then after all the temporary tables have been created I drop the existing tables, rename the temporary tables, and add foreign keys and indexing to the new tables to speed up joins and querying.
The issue I'm having is the original primary key references are remaining. So when I go to update again I get
Exception: There is already an object named 'PK_maintenance_event_id'
in the database. Could not create constraint.
I'm wondering what is the best course of action is? Should I not set the primary key when I create the temporary table and instead add it to the table after it has been renamed? Or is there a way to rename constraints so that when I rename the table I can change the name of the primary key constraint.
After the original tables have been dropped I want there to be as little downtime as possible, but anything that happens before the tables have been dropped can take a really long time and it won't matter.
If your temp tables need that constraint
When create
use
CONSTRAINT [PK_maintenance_event_id_temp"]
instead of
CONSTRAINT [PK_maintenance_event_id]
when you rename temp back to real table
exec sp_rename [PK_maintenance_event_id_temp], [PK_maintenance_event_id]

Dropping table in SQL with Constraint

I'm trying to drop a table in Northwind, and I'm getting:
ALTER TABLE DROP COLUMN Region failed because one or more objects access this column.
I'm using:
use [NorthWind]
go
alter table dbo.Customers
drop column Region
I guess it's because there is a constraint on the column Region. How do I find out which constraint I need to remove?
EXEC sp_MSforeachtable #command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"
GO
OR
ALTER TABLE table_Name NOCHECK CONSTRAINT all
OR
ALTER TABLE table_Name NOCHECK CONSTRAINT constraint_name
Then try with your SQL.
Please use this when you really want to drop constraints no matter other tables affected.
If disabling the constraints is not enough, you will have to drop the constraints.
You must drop Constraint first and then drop the table.If you have SQL Server Management Studio you can select the constraint and delete it using GUI. Or you can use command line to drop your constraints
How to remove foreign key constraint in sql server?. Taken from this answer
ALTER TABLE <TABLE_NAME> DROP CONSTRAINT <FOREIGN_KEY_NAME>
If you want to go via Sql Server Management Studio on the object explorer window, right click on the object you want to drop,then click view dependencies.
First, you should know the ForeignKey - Constraint. After that, you must drop it.
Something like this:
-- looking for the Constraint's name related the dbo.Customers table
SELECT Table_Name,Constraint_Name
FROM Information_Schema.CONSTRAINT_TABLE_USAGE
WHERE Table_Name 'Customers'
-- Drop/Delete the founded constraint
ALTER TABLE [dbo].[Customers] DROP CONSTRAINT [FOREIGN_KEY_NAME]
Then, you'll run your actual script.

Delete rows with foreign key in PostgreSQL

I would like to delete rows which contain a foreign key, but when I try something like this:
DELETE FROM osoby WHERE id_osoby='1'
I get this statement:
ERROR: update or delete on table "osoby" violates foreign key constraint "kontakty_ibfk_1" on table "kontakty"
DETAIL: Key (id_osoby)=(1) is still referenced from table "kontakty".
How can I delete these rows?
To automate this, you could define the foreign key constraint with ON DELETE CASCADE.
I quote the the manual for foreign key constraints:
CASCADE specifies that when a referenced row is deleted, row(s)
referencing it should be automatically deleted as well.
Look up the current FK definition like this:
SELECT pg_get_constraintdef(oid) AS constraint_def
FROM pg_constraint
WHERE conrelid = 'public.kontakty'::regclass -- assuming public schema
AND conname = 'kontakty_ibfk_1';
Then add or modify the ON DELETE ... part to ON DELETE CASCADE (preserving everything else as is) in a statement like:
ALTER TABLE kontakty
DROP CONSTRAINT kontakty_ibfk_1
, ADD CONSTRAINT kontakty_ibfk_1
FOREIGN KEY (id_osoby) REFERENCES osoby (id_osoby) ON DELETE CASCADE;
There is no ALTER CONSTRAINT command. Drop and recreate the constraint in a single ALTER TABLE statement to avoid possible race conditions with concurrent write access.
You need the privileges to do so, obviously. The operation takes an ACCESS EXCLUSIVE lock on table kontakty and a SHARE ROW EXCLUSIVE lock on table osoby.
If you can't ALTER the table, then deleting by hand (once) or by trigger BEFORE DELETE (every time) are the remaining options.
One should not recommend this as a general solution, but for one-off deletion of rows in a database that is not in production or in active use, you may be able to temporarily disable triggers on the tables in question.
In my case, I'm in development mode and have a couple of tables that reference one another via foreign keys. Thus, deleting their contents isn't quite as simple as removing all of the rows from one table before the other. So, for me, it worked fine to delete their contents as follows:
ALTER TABLE table1 DISABLE TRIGGER ALL;
ALTER TABLE table2 DISABLE TRIGGER ALL;
DELETE FROM table1;
DELETE FROM table2;
ALTER TABLE table1 ENABLE TRIGGER ALL;
ALTER TABLE table2 ENABLE TRIGGER ALL;
You should be able to add WHERE clauses as desired, of course with care to avoid undermining the integrity of the database.
There's some good, related discussion at http://www.openscope.net/2012/08/23/subverting-foreign-key-constraints-in-postgres-or-mysql/
You can't delete a foreign key if it still references another table.
First delete the reference
delete from kontakty
where id_osoby = 1;
DELETE FROM osoby
WHERE id_osoby = 1;
It's been a while since this question was asked, hope can help.
Because you can not change or alter the db structure, you can do this. according the postgresql docs.
TRUNCATE -- empty a table or set of tables.
TRUNCATE [ TABLE ] [ ONLY ] name [ * ] [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
Description
TRUNCATE quickly removes all rows from a set of tables. It has the same effect as an unqualified DELETE on each table, but since it does not actually scan the tables it is faster. Furthermore, it reclaims disk space immediately, rather than requiring a subsequent VACUUM operation. This is most useful on large tables.
Truncate the table othertable, and cascade to any tables that reference othertable via foreign-key constraints:
TRUNCATE othertable CASCADE;
The same, and also reset any associated sequence generators:
TRUNCATE bigtable, fattable RESTART IDENTITY;
Truncate and reset any associated sequence generators:
TRUNCATE revinfo RESTART IDENTITY CASCADE ;
It means that in table kontakty you have a row referencing the row in osoby you want to delete. You have do delete that row first or set a cascade delete on the relation between tables.
Powodzenia!
One can achieve this by issueing an extra SQL script that deletes the records related via the FK.
For this, using subselect in WHERE clause of a DELETE command can simply do what is needed.
Something similar to:
DELETE FROM kontakty
WHERE fk_column_from_kontakty_matching_id_osoby IN (
SELECT id_osoby FROM osoby WHERE id_osoby = '1'
);
DELETE FROM osoby WHERE id_osoby = '1';
the example assumes the FK column from kontakty matching osoby.id_osoby is called fk_column_from_kontakty_matching_id_osoby as it cannot be interpolated from the error message provided
For the case of OP's the query could by simplified a lot, but I have decided to leave it like this for it demonstrates accomplishing more complex scenarios
This approach is quite useful for SQL migrations, where one cannot depend on an assigned id and where ids cannot be easily fetched first and acted upon later.

What can I do about a SQL Server ghost FK constraint?

I'm having some trouble with a SQL Server 2005 database that seems like it's keeping a ghost constraint around. I've got a script that drops the constraint in question, does some work, and then re-adds the same constraint. Normally, it works fine. Now, however, it can't re-add the constraint because the database says that it already exists, even though the drop worked fine!
Here are the queries I'm working with:
alter table individual drop constraint INDIVIDUAL_EMP_FK
ALTER TABLE INDIVIDUAL
ADD CONSTRAINT INDIVIDUAL_EMP_FK
FOREIGN KEY (EMPLOYEE_ID)
REFERENCES EMPLOYEE
After the constraint is dropped, I've made sure that the object really is gone by using the following queries:
select object_id('INDIVIDUAL_EMP_FK')
select * from sys.foreign_keys where name like 'individual%'
Both return no results (or null), but when I try to add the query again, I get:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "INDIVIDUAL_EMP_FK".
Trying to drop it gets me a message that it doesn't exist. Any ideas?
It means the data is wrong on creation of the FK
That is, you have "EMPLOYEE_ID" values in the INDIVIDUAL child table that don not exist in the parent EMPLOYEE table.
You could use ALTER TABLE ...WITH NOCHECK ADD CONSTRAINT... but then the FK is no use