Not able to delete records from table(order) having its id column as foreign key in multiple order tables in postgres - sql

I have an "orders" table
with its id as foreign key in below tables
dispatch_details
order_histories
sales_return_details
promotion_orders
While creating the table we haven't added ON DELETE CASCADE.
so I have deleted all the required records from referenced tables i.e. dispatch_details,
order_histories, sales_return_details and promotion_orders.
It's taking way too much time still not able to delete records from orders even though I am not getting any error. It is only processing but doesn't complete.
I have further added index for all the referenced table.
create index idx_dispatch_details_order_id on dispatch_details(order_id);
create index idx_order_histories_order_id on order_histories(order_id);
create index idx_sales_return_details_order_id on sales_return_details(order_id);
create index idx_promotion_orders_order_id on promotion_orders(order_id);
Still, I am not able to delete the records.
Is there any way to delete the records table from orders efficiently? Currently, I am not able to delete even single records from orders.

I have further added an index to all table calls and daily_order_info table. Also, the orders table has parent_order_id FK reference to itself. Added index for that column as well. Basically, for all the tables referenced: created an index and that solved my issue.

Related

If I delete a record from a table it is deleted at many other places

I am working on a database built by the previous team. I have to delete certain records from a table (Example shown below).
DELETE FROM table WHERE id = 5541
While doing this process, some records from the other tables with the same id is getting deleted. Could someone help how to overcome this problem?
In SQL Server, there is statement called ON DELETE CASCADE which deletes the record from the child table if the record is deleted from the parent table. This can be set using the ALTER STATEMENT as shown below. To remove the cascading, try altering the child table back to default. The default is NO CASCADING.
ALTER TABLE ChildTable
ADD CONSTRAINT FKey
FOREIGN KEY (col1, col2, ... coln)
REFERENCES ParentTable (Pcol1, Pcol2, ... Pcoln)
ON DELETE CASCADE
There is UPDATE CASCADE as well if the data in the child table should be updated when the parent table is updated.
You database most certainly contains foreign key constraints with cascading deletes see docs.
You may be able to remove these foreign keys, but of course, then deleting some rows will leave you with inconsistent data.
Another possibilty is to just remove the cascading deletes. But then of course, you won't be able to delete any rows which are referenced by records from other tables, as SQL server will ensure the consistency of your data.

Generating PL/SQL script to create copy of records from many related tables

For a given table and the unique ID of one record in that table, what's the easiest/quickest to generate a PL/SQL (or SQL) script that creates a copy of that record, then creates copies of all records from tables with a foreign key relationship to that record, and then all tables with a foreign key relationship to those 2nd tier records, and so on until all related records in all directly or indirectly related tables in the schema have been copied?
Such a script would be useful in capturing and reproducing the state of a record and all descendant records for testing purposes.
Considerations:
Schema has 500+ tables so writing this script manually would be slow.
Avoid unique constraint violations by ensuring that the new records have their own generated/altered primary key values. Generate new IDs using max(id_column) + 1 rather than sequence, to simplify problem.
Use Oracle metadata tables to gather list of tables, and maybe primary key and foreign key columns (?).
Thanks.
Assuming the FKs are present and valid, you would drive this from dba_constraints, starting with r_constraint_name = the PK constraint of the start table. For each table found, you would query dba_tab_columns and build your queries and generated inserts from here. You would do this recursively to capture all the tables in the tree. To make it easier, I would generate a stored procedure table_ins wrapper, so that when you generate you INSERT you instead call the store_proc to avoid having to generate the INSERT ( col1, .... ) for each row.

ON DELETE CASCADE alternatives and performance (SQL Server)

In my program I store entries in a table and an entry may also have child items.
id uniqueidentifier not null primary key
parent uniqueidentifier null (another id from the same table or null)
... other columns
In this table only top-level entries can have child items, so cycles or recursion are not possible.
If I delete an entry, I want also delete child items. Unfortunately, there is no way to add ON DELETE CASCADE to such table:
Introducing FOREIGN KEY constraint '...' on table '...' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
I can, however, just specify an additional condition in my delete statement to do the same:
DELETE FROM mytable WHERE id = #GUID OR parent = #GUID
The problem is that parent column is not indexed. This column also has a lot of duplicate values (NULLs) and as I know, duplicate values are very bad when used with indexes. I would like to know, what is the best solution for this problem
Is there a better solution to remove both child and parent items?
Should I use index on parent column and if yes, what type of index should I use in this case - there are a lot of duplicate values
Not sure, but I suggest that OR-statement in the above solution make primary key index useless and SQL server will just scan the entire table.
PS
I cannot create another table to store child items.

Unique clustered index on two columns for an indexed view

I'm trying to setup an indexed view on a table that doesn't have a unique id. It has two unique identifiers that if combined would be unique for it's row. I'm having trouble actually creating the unique clustered index that the indexed view requires when I found an thread on MSDN that folks all agree it is possible to create a unique clustered index out of 2 columns for a indexed view # http://social.msdn.microsoft.com/Forums/en/transactsql/thread/f2c99845-3af1-46e8-9b52-363c24988744
But for the life of me, can't figure out how to create it. I'm rolling with this query, but it doesn't seem to cut it.
CREATE UNIQUE CLUSTERED INDEX [PK] ON MyView
(
MyId1, MyId2
)
Error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key
was found for the object name 'dbo.MyView' and the index name 'PK'.
The duplicate key value is (71cd9b68-1a9e-47bc-bc6b-0008b230a6d8,
0e64aa3a-0631-4caf-82d9-73609ee79b19).
The two IDs listed as duplicates are IDs from MyId2.
So, how could I create a unique clustered index here?
Well the error message seems to suggest that there is more than one record where MyId1 = 71cd9b68-1a9e-47bc-bc6b-0008b230a6d8 and MyId2 = 0e64aa3a-0631-4caf-82d9-73609ee79b19.
I would recommend running a query that selects based only on that criteria and confirming that this only returns one record. If it returns more, then you cannot recreate a UNIQUE constraint on these two columns unless you eliminate the duplicates.

ON UPDATE CASCADE with two columns in a single table in SQL Server [duplicate]

I have a database table called Lesson:
columns: [LessonID, LessonNumber, Description] ...plus some other columns
I have another table called Lesson_ScoreBasedSelection:
columns: [LessonID,NextLessonID_1,NextLessonID_2,NextLessonID_3]
When a lesson is completed, its LessonID is looked up in the Lesson_ScoreBasedSelection table to get the three possible next lessons, each of which are associated with a particular range of scores. If the score was 0-33, the LessonID stored in NextLessonID_1 would be used. If the score was 34-66, the LessonID stored in NextLessonID_2 would be used, and so on.
I want to constrain all the columns in the Lesson_ScoreBasedSelection table with foreign keys referencing the LessonID column in the lesson table, since every value in the Lesson_ScoreBasedSelection table must have an entry in the LessonID column of the Lesson table. I also want cascade updates turned on, so that if a LessonID changes in the Lesson table, all references to it in the Lesson_ScoreBasedSelection table get updated.
This particular cascade update seems like a very straightforward, one-way update, but when I try to apply a foreign key constraint to each field in the Lesson_ScoreBasedSelection table referencing the LessonID field in the Lesson table, I get the error:
Introducing FOREIGN KEY constraint 'c_name' on table 'Lesson_ScoreBasedSelection' may cause cycles or multiple cascade paths.
Can anyone explain why I'm getting this error or how I can achieve the constraints and cascading updating I described?
You can't have more than one cascading RI link to a single table in any given linked table. Microsoft explains this:
You receive this error message because
in SQL Server, a table cannot appear
more than one time in a list of all
the cascading referential actions that
are started by either a DELETE or an
UPDATE statement. For example, the
tree of cascading referential actions
must only have one path to a
particular table on the cascading
referential actions tree.
Given the SQL Server constraint on this, why don't you solve this problem by creating a table with SelectionID (PK), LessonID, Next_LessonID, QualifyingScore as the columns. Use a constraint to ensure LessonID and QualifyingScore are unique.
In the QualifyingScore column, I'd use a tinyint, and make it 0, 1, or 2. That, or you could do a QualifyingMinScore and QualifyingMaxScore column so you could say,
SELECT * FROM NextLesson
WHERE LessonID = #MyLesson
AND QualifyingMinScore <= #MyScore
AND #MyScore <= QualifyingMaxScore
Cheers,
Eric