Click here to Skip to main content
15,891,777 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi there.

The problem I have is a simple one really, but I have no clue how to write an efficient SQL statement to carry it out.

The problem is this:

In the data base that is being updated there is 3 tables that need to be changed depending on the data in the related table.

So

Table A is parent to Table B (A.Pk is B.Fk)
Table B is parent to Table C (B.Pk is C.Fk)

When all fields in C are all closed where C.Fk = B.Pk Then
The related row in table B is closed and
When all fields in B are all closed where B.Fk = A.Pk Then
The related row in table A is closed and

The issue I have is that i do not want to iterate through each table n times using a curser, as this could cause other components to fail due to locks.

I would be most greatful if anyone can help.
Posted

1 solution

I am not that hot in SQL but here is my attempt.
The query are quite simple at the end:
SQL
CREATE TABLE A(Id int NOT NULL PRIMARY KEY)
CREATE TABLE B(Id int NOT NULL PRIMARY KEY, A int NOT NULL)
CREATE TABLE C(Id int NOT NULL PRIMARY KEY, B int NOT NULL, Closed BIT)

-- You can have foreign key references or not
--ALTER TABLE B ADD CONSTRAINT FK_B_A FOREIGN KEY(A) REFERENCES A(Id)
--ALTER TABLE C ADD CONSTRAINT FK_C_B FOREIGN KEY(B) REFERENCES B(Id)

INSERT INTO A VALUES (1),(2),(3)
INSERT INTO B VALUES (10,1), (11,1),(12,1)
INSERT INTO B VALUES (20,2), (21,2),(22,2)

INSERT INTO C VALUES (100,10,0),(101,10,0),(102,10,0)
INSERT INTO C VALUES (110,11,0),(111,11,0),(112,11,1)
INSERT INTO C VALUES (120,12,0),(121,12,1),(122,12,1)
INSERT INTO C VALUES (200,20,1),(201,20,0),(202,20,1)
INSERT INTO C VALUES (210,21,1),(211,21,1),(212,21,1)
-- nothing in 22

------------------------------------------------------
-- DELETE C RECORDS
------------------------------------------------------
-- this is required if you have the Foreign keys
DELETE FROM C WHERE C.Closed = 1

------------------------------------------------------
-- DELETE B RECORDS
------------------------------------------------------
DELETE FROM B
    WHERE NOT EXISTS(SELECT * FROM C WHERE C.B = B.ID)

-- or if you have no foreign keys and want to keep the C records:
DELETE FROM B
    WHERE NOT EXISTS(SELECT * FROM C WHERE C.B = B.ID AND C.Closed = 0)

------------------------------------------------------
-- DELETE A RECORDS
------------------------------------------------------
DELETE FROM A
    WHERE NOT EXISTS(SELECT * FROM B WHERE B.A = A.ID)

------------------------------------------------------
-- Results
------------------------------------------------------

SELECT * FROM A

--     Id
--     -----------
--     1
--     2

-- A(3) is gone


SELECT * FROM B

-- B(21) is gone
-- B(22) is gone

--   Id          A
--   ----------- -----------
--   10          1
--   11          1
--   12          1
--   20          2

SELECT * FROM C

--     Id          B           Closed
---- ----------- ----------- ------
--   100         10          0
--   101         10          0
--   102         10          0
--   110         11          0
--   111         11          0
--   120         12          0
--   201         20          0

-- All the closed are gone

DROP TABLE C
DROP TABLE B
DROP TABLE A
 
Share this answer
 
v2
Comments
Sandeep Mewara 24-Jun-12 15:09pm    
Nice explained answer. 5!
Maciej Los 24-Jun-12 18:14pm    
Good work, my 5!
JonCox 25-Jun-12 15:59pm    
Thank you for your answer. I have however come up with a different alternative that does not require creating temp tables, I am in the process of testing it. However if it does not work I will impliment this solution so thank you again
Pascal Ganaye 25-Jun-12 16:16pm    
Just for the record those are your actual tables not temp-tables.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900