TRUNCATE TABLES with CONSTRAINTS - sql

Is there a way to truncate tables with constraints ?
I tried to DEACTIvATE with this:
DECLARE #SQLtxt varchar(max)
SET #SQLtxt = '-- DESACTIVER LES CONTRAINTES' + CHAR(10)
SELECT #SQLtxt = #SQLtxt + 'ALTER TABLE [' + name + '] NOCHECK CONSTRAINT ALL;' FROM sys.tables
PRINT #SQLtxt
Of course, it didn't worked. I have to drop the constraint then recreate them ! The only way I could make it work is by extracting the script to drop and recreate the contraint.
Is there another way ? BTW I don't want to delete because it would use the Transaction Log.

Here is a script that may help you get going scripting out FK's. Script out your foreign keys.
I use a modified version to dump the constraint definitions into a temp table, then do the TRUNCATE magic and then recreate the constraints from the temp table. However, this is only for my own convenience when restoring the production database onto a non-production environment to get rid of most of the data. Not sure, I would use it in a production scenario though. I would rather prefer deleting in small batches knowing that everything is fully logged.
Btw, womb's reference to the SQL Server 2000 Books Online is a bit misleading. TRUNCATE TABLE has always been a minimally logged operation.
TRUNCATE TABLE removes the data by deallocating the data pages used to store the table's data, and only the page deallocations are recorded in the transaction log.
This is has specified more precisely in later versions of Books Online.

The TRUNCATE command will not work on tables with FK references. Straight from the documentation:
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.

You sort of answered the question yourself - if there's a foreign key referencing your table, SQL Server needs that information in the transaction log. Since TRUNCATE TABLE effectively bypasses the log, it's not allowed on tables referenced by foreign keys.
You'll either have to DROP the foreign key constraint, or use a DELETE statement.

It's only referencing (eg the REFERENCES bit) foreign keys you need to drop.
This should make it easier...

Related

Oracle 11g SQL Disable foreign key constraints and drop table

When I have issued a
ALTER TABLE table DISABLE CONSTRAINT fk1
and when I then try to drop the table
DROP TABLE table
That the constraint is still checked even though it is disabled.
Have I missed something?
You have to drop the constraints as well in order drop a table. Try the following:
DROP TABLE someTable CASCADE CONSTRAINTS;
DISABLE CONSTRAINT works for update/insert statements.
See oracle help.
Disabling Constraints
To enforce the rules defined by integrity constraints, the constraints
should always be enabled. However, consider temporarily disabling the
integrity constraints of a table for the following performance
reasons:
When loading large amounts of data into a table
When performing batch operations that make massive changes to a table
(for example, changing every employee's number by adding 1000 to the
existing number)
When importing or exporting one table at a time
You are trying to drop your table. It is not designed to for this. You need to DROP CONSTRAINTs.

monetdb - copy into from...requires tables without indices

I get this error with Monetdb when I try to load .tbl data in tables where there are primary key and foreign key, what's wrong?
This is the command:
COPY INTO monet.CUSTOMER FROM '/home/nicola/Scrivania/ssb-dbgen-master/1gb/customer.tbl' USING DELIMITERS '|', '|\n' LOCKED;
It is always good to bulk-load into tables with (foreign-) keys disabled. You can add them after the load with the ALTER statement.
see https://www.monetdb.org/Documentation/Cookbooks/SQLrecipes/LoadingBulkData
Another part of MonetDB's documentation says: "WARNING It is advised to add integrity constraints to the table after the file has been loaded. The ALTER statements perform bulk integrity checking and perform these checks often more efficiently." https://www.monetdb.org/Documentation/Manuals/SQLreference/CopyInto
Generally, for bulk loading into an existing table, is is advised to drop the indexes/foreign keys/other constraints, load the table, and then recreate the indexes/foreign keys/other constraints.

TRUNCATE TABLE query unable to execute in SSIS because of foreign key

I have a table Person which contains 2 fields.In my another database i have a Participant Table(also have 2 columns).From Participant Table i have to insert values into Person Table.
but before every insertion,i want truncate the person Table.
I have try it out with linking Execute Sql task to Data flow task.But it is showing error that a Primary Foreign key relation exists there.
If I understand correctly, SSIS has nothing to do with your real problem, which is that you want to truncate a table that is referenced by a foreign key constraint. That question has already been answered: Cannot truncate table because it is being referenced by a FOREIGN KEY constraint?
If a table in sql server has foreign key references then you can't truncate. instead in your execute sql task use delete without a where clause.
delete from person_table
If you are really adamant about truncating the table, you could drop the foreign key constraints, then truncate the table then recreate the foreign key constraints. Providing of course, that the user you are running the package as has the privileges to do so.
Create an "Execute SQl" task and run DELETE FROM person
after this task, run your import.
DELETE FROM will give the same result as TRUNCATE TABLE, but if the table has a foreign key pointing to it, it cant be truncated. You have to use the delete command
You won't be able to delete either unless cascading deletes is turned on (or you delete the child records first). Why is this a problem you ask, why can't I do what I want to do? Because if you do then you may lose the integrity of the data. Suppose I have records in table2 which relate to records in table 1. Suppose further that table1 has an autogenerated id. If I could truncate that table, then I leave those records i ntable 2 hanging out without any record to reference them, they have become orphaned. Well but I'm putting the data back in you say. But then they will have new id numbers and you will still lose the relatinoship tothe related data.
Can you drop the FK and truncate and insert and recreate the FK. Yes you can but it is a poor practice and you should not unless you are also recreating those related records.
The best practice is to use a MERGE statement to update or insert depending on what you need.
In SSIS Transfer SQL Server Objects Task Set Property DeleteFirst to TRUE

SQL add Foreign key constraint with check

I have the following query which is adding contraint.
but in order to add, i want to check if this key has already been used or not?
ALTER TABLE HL7_MessageHierarchy
ADD CONSTRAINT fk_vMessageType FOREIGN KEY (vMessageType)
REFERENCES HL7_MessageType(vMessageType);
for example. if i have to add a column, i can easily check if the table exists in sysobjects and its respective column exists in syscolumns.
Is it possible to use the query multiple times without GO and without making any error indeed? if yes then how ???
[EDIT]
I don't know why my browser not allowing me to add comments so i am adding to Edit.
I want to check if there exists any foreign key with same name. so if there is no data even then the query can make problem because the key may already be existing. I want to run the above script clean (ofcourse resident data does matter but that is perhaps a straight forward check?)
[EDIT]
my bad, i must have known that version is important... I believe its 2005... (will love to know if someone can tell for other versions too)
I assume you mean
check the HL7_MessageHierarchy for values not inHL7_MessageType"
So, a query like this will tell you
SELECT *
FROM HL7_MessageHierarchy H
WHERE NOT EXISTS (SELECT *
FROM HL7_MessageType T
WHERE H.vMessageType = T.vMessageType)
Also, I'd recommend using WITH CHECK too
ALTER TABLE HL7_MessageHierarchy WITH CHECK ADD
CONSTRAINT fk_vMessageType FOREIGN KEY (vMessageType)
REFERENCES HL7_MessageType(vMessageType);
In SQL 2005, the recommended way of checking for the existence of objects is Catalog Views. The one you want is sys.foreign_keys:
IF NOT EXISTS ( SELECT * FROM sys.foreign_keys
WHERE name = 'fk_vMessageType' )
BEGIN
EXEC ('
ALTER TABLE HL7_MessageHierarchy
ADD CONSTRAINT fk_vMessageType FOREIGN KEY (vMessageType)
REFERENCES HL7_MessageType(vMessageType)
')
END
I have wrapped the creation in EXEC to avoid confusing the parser.

What is the equivalent effect to Truncating a table, when the table is referenced by a foreign-key

Straight out of the MSDN docs for Sql Server 2005:
You cannot use TRUNCATE TABLE on tables that:
Are referenced by a FOREIGN KEY constraint.
Participate in an indexed view.
Are published by using transactional replication or merge replication.
I want the effect of a TRUNCATE (specifically the fact that it resets IDENTITY type columns), but I can't use one in my case because my table is referenced by a foreign-key elsewhere in the database.
Update: This is for a testing configuration where I am clearing out the referencing table as well, so foreign-key integrity is a non-issue.
What other ways are there to get around this?
You can delete all the rows and then do a DBCC CHECKIDENT (Tablename, RESEED, 0) to reset the identity seed
But again DELETE is fully logged while TRUNCATE is minimally logged and will be many times faster
Another option is to drop the foreign key constrains then do a truncate and then recreating the foreign key constraints
The fact that it is refernced by a foreign key is the clue you need to not truncate a table or you would be creating orphaned records. This is why truncate table is not allowed if a foreign key exists.
The correct process is to first delete the refernced records, if any, then drop the FK constraint, then truncate the table then reinstate the fk constraint. If you skip step one, you will create a data integrity nightmare where the record pointing to oldid 100 is not pointing to the new record that happens to get assigned to 100 and it isn;t the record it should match to.
You can drop the foreign key, truncate the table, and then recreate the foreign key.
You will need to drop the constraint, trunc the table, and then add the constraint back. However, you should be very careful with this. If there are rows in the table that you are dropping the FK reference to you will not be able to add it until those rows are deleted or the FK column in the other table is clear.