SQL Server Delete Order for FKC? - sql-server

I have a tree table that has foreign keys to self (depth-unlimited parents and children). Given that SQL Server lacks the CASCADE (within same table, loops) support MySQL offers, I need to first order the IDs to delete before deleting them. I order them with a CTE from most-deletable (no children) to least-deletable (top parents).
I want to throw this set of IDs to a DELETE but I need them deleted in the exact order I send them to SQLServer. Can this be done in a single query?
I could write a stored procedure to delete the records or just DELETE one by one with multiple queries from C#... but I'm wondering if this can be achieved in a simple DELETE FROM WHERE IN query? I have no clue if DELETE retains order of the IN (...) collection, because if it doesn't... the FKC will block it. -- Coming from MySQL, never cared as they can cascade within the same table.

Related

Delete records using Informatica PowerCenter

I have simple mapping which deletes records in the target table. I have not used "UPDATE STRATEGY" transformation, rather set session property "delete" in order to delete records.
The said table is having composite primary keys (having 10 columns). It is working fine if all these columns are having value. BUT there are few records in which one of the column has NULL value. In this scenario, it is not deleting that record.
Can someone let me know how to handle this situation?
Its possible, because informatica fires sql like this when deleting data - delete from tab where key1=v1 and key2=v2. So, if v2 is null, its possible, delete query will ignore the record.
You can use target update override property to do this. Write your own sql to delete data.
DELETE FROM
mytable
WHERE
ID = :TU.ID
AND ISNULL(EMP_NAME,'Unspecified') = ISNULL(:TU.EMP_NAME,'Unspecified')
Since you have keys defined in infa you shouldnt face any problem. But please note that these deletes will be done on a row by row basis, so if it's a large table, and delete doesnt follow primary key index, the delete it could take time to delete each row!

Trigger/Constraints for deleting table hierarchy

I have the following table structure which stores some results of my application. Each hierarchy level has a data row attached which again consists of multiple values. A data row is exclusively assigned to a single table of the hierarchy tables, not many in parallel. My goal is to delete the Parent including all hierarchy levels, the data and values.
My first attempt was to add ON DELETE CASCADE constraints everywhere but ON DELETE CASCADE does not work with a diamond structure. It results in:
Introducing FOREIGN KEY constraint 'FK_Data_Hierarchy2' on table 'Data' may cause cycles or cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other KEY constraints.
Then my second attempt was to remove the cascade constraint on the Data table and add a INSTEAD OF DELETE trigger to Hierarchy 1-3 which deletes the Data entries before the own rows. But also there the SQL Server complains that you cannot add such a trigger due to the ON DELETE CASCADE which is there for the hierarchy nesting.
Cannot create INSTEAD OF DELETE or INSTEAD OF UPDATE TRIGGER 'TR_Hierarchy1_Delete' on table 'dbo.Hierarchy'. This is because the table has a FOREIGN KEY with cascading DELETE or UPDATE.
My last plan would be to remove all ON DELETE CASCADE constraints and delete the whole tree manually in a trigger. But this is quite a challenge do it in an optimized fashion.
What is really the best solution for this job? Iterating over the rows using cursors? (possibly slow due to iteration)
Use combined joins to select the affected rows for every individual table? (possibly slow due to redundant joining the whole hierarchy)
Or does somebody know a trick how to delete over multiple tables using a result set?

Generate custom EF6 code first migration SQL after foreign key constraints

I'm adding custom SQL to an EF6 code first migration. The SQL adds delete triggers to various tables. It's generating correct syntax and getting output as expected.
But the location of the output is giving me trouble. Code first migrations put all the foreign key constraints at the bottom of the generated SQL. When creating the constraints for a join table (used in a many-to-many association), the ON DELETE CASCADE clause is added. All fine and dandy, except when I've added a delete trigger to one of the tables participating in that relationship -- cascade delete isn't allowed coming from a table with a delete trigger on it.
Ideally, I'd like to do one of two things -- either move my SQL to the bottom of the script (where I can yank the cascade deletes off the constraints after they're added) or somehow tell EF not to cascade delete certain particular join tables, while leaving the default behavior in place for the more common case where the cascade deletes are the correct thing to do.
Anyone have a clue as to how this can be done?
Thanks.

See what will cascade delete before running the delete

Is there a way with SQL Server to see what will be deleted before the actual delete is run?
Say I have a customer table that Foreign Keys to orders and addresses with cascading deletes.
If I delete a customer then SQL Server will delete all the orders and addresses for that customer too.
Is there a way to get the Primary keys for the tables that will have deletes done on them without running the actual delete statement?
NOTE: Obviously I could code a sproc by hand to do this for this specific example. But my question is asking if the way SQL Server does it (for the delete) can be used to get info rather than just do the delete.
The only way I know of to do this is to:
start a transaction
run your deletion
select from tables
roll back your transaction

Sql server bulk delete by known record ids

I need to delete many rows from sql server 2008 database, it must be scalable so I was thinking about bulk delete, the problem is that the are not many references on this, at least in my case.
The first factor is that I will exactly know the ID of every row to delete, so any tips with TOP are not an option, also I will delete less rows that I want to retain so there will be no need for some "drop/temp table/re-create" methods.
So I was thinking to use WHERE IN , either suppling IDs or xml data with IDs, there is also an option to use MERGE to delete rows.
If I will have to delete 1000+ rows, sending all ids to WHERE IN could be a problem ? And what with MERGE - it is really a cure for all bulk insert/update/delete problems? What to choose?
One option would be to store the known ID's into a "controller" table, and then delete rows from your main data table that have their ID show up in the controller table.
That way, you could easily "batch" up your deletes, e.g.
DELETE FROM dbo.YourMainDataTable
WHERE ID IN (SELECT TOP (250) ID FROM dbo.DeleteControllerTable)
You could easily run this delete statement in e.g. a SQL Agent Job which comes around every 15 minutes to check if there's anything to delete. In the meantime, you could add more ID's to your DeleteController table, thus you could "decouple" the process of entering the ID's to be deleted from the actual deletion process.

Resources