Jul 23, 2005
/*This is a long post. You can paste the whole messagein the SQL Query Analyzer.I have a scenario where there are recordswith values pointing to wrong records and I need to fix themusing an Update statement.I have a sample code to reproduce my problem.To simplify the scenario I am trying to use Order relatedtables to explain a little better the tables i have to work with.Please don't bother looking at the wrong relationship and howthe tables are designed. That's not my current problem. Myjob is to correct the wrong data either using code or manually.Here are the tables I have created:TBLORDERS where two fields I am interested in are:ORDERTYPENO linking to TBLORDERTYPELASTSTATUSNO linking to TBLSTATUSTBLORDERTYPE where one field I am interested in isORDERPROCESSINGNOTBLORDERPROCESSINGEach order has a link to OrderTypeNo and eachOrderTypeNo has a link to OrderProcessingNo.TBLORDERSTATUSES where one field I aminterested in isSTATUSNOTBLSTATUS where one field I am interested in isORDERPROCESSINGNOI have the sample code here:*/--DROP DATABASE TestDBCREATE DATABASE TestDBGOUSE TestDBCREATE TABLE TBLORDER(IDNO INT PRIMARY KEY NOT NULL,ORDERNUMBER VARCHAR(50),ORDERTYPENO INT,LASTSTATUSNO INT)INSERT INTO TBLORDER (IDNO, ORDERNUMBER, ORDERTYPENO, LASTSTATUSNO)SELECT 1, 'ORDERTEST1', 1, 3 UNION ALLSELECT 2, 'ORDERTEST2', 1, 3 UNION ALLSELECT 3, 'ORDERTEST3', 2, 16 UNION ALLSELECT 4, 'ORDERTEST4', 2, 16 UNION ALLSELECT 5, 'ORDERTEST5', 2, 16 UNION ALLSELECT 6, 'ORDERTEST6', 2, 16 UNION ALLSELECT 7, 'ORDERTEST7', 4, 5 UNION ALLSELECT 8, 'ORDERTEST8', 4, 5 UNION ALLSELECT 9, 'ORDERTEST9', 6, 22 UNION ALLSELECT 10, 'ORDERTEST10', 6, 22 UNION ALLSELECT 11, 'ORDERTEST11', 7, 20CREATE TABLE TBLORDERSTATUSES(IDNO INT PRIMARY KEY NOT NULL,ORDERNO INT,STATUSNO INT)INSERT INTO TBLORDERSTATUSES (IDNO, ORDERNO, STATUSNO)SELECT 1, 1, 1 UNION ALLSELECT 2, 1, 2 UNION ALLSELECT 3, 1, 3 UNION ALLSELECT 4, 1, 4 UNION ALLSELECT 5, 2, 1 UNION ALLSELECT 6, 2, 2 UNION ALLSELECT 7, 2, 3 UNION ALLSELECT 8, 2, 4 UNION ALLSELECT 9, 3, 15 UNION ALLSELECT 10, 3, 16 UNION ALLSELECT 11, 3, 17 UNION ALLSELECT 12, 4, 15 UNION ALLSELECT 13, 4, 16 UNION ALLSELECT 14, 4, 17 UNION ALLSELECT 15, 5, 15 UNION ALLSELECT 16, 5, 16 UNION ALLSELECT 17, 5, 17 UNION ALLSELECT 18, 6, 15 UNION ALLSELECT 19, 6, 16 UNION ALLSELECT 20, 6, 17 UNION ALLSELECT 21, 7, 5 UNION ALLSELECT 22, 7, 6 UNION ALLSELECT 23, 8, 5 UNION ALLSELECT 24, 8, 6 UNION ALLSELECT 25, 9, 22 UNION ALLSELECT 26, 9, 23 UNION ALLSELECT 27, 9, 24 UNION ALLSELECT 28, 9, 25 UNION ALLSELECT 29, 10, 22 UNION ALLSELECT 30, 10, 23 UNION ALLSELECT 31, 10, 24 UNION ALLSELECT 32, 10, 25 UNION ALLSELECT 33, 11, 18 UNION ALLSELECT 34, 11, 19 UNION ALLSELECT 35, 11, 20 UNION ALLSELECT 36, 11, 21CREATE TABLE TBLORDERTYPE(IDNO INT PRIMARY KEY NOT NULL,ORDERTYPE VARCHAR(50),ORDERPROCESSINGNO INT)INSERT INTO TBLORDERTYPE (IDNO, ORDERTYPE, ORDERPROCESSINGNO)SELECT 1, 'CATEGORY 100', 1 UNION ALLSELECT 2, 'CATEGORY 200', 5 UNION ALLSELECT 3, 'CATEGORY 300', 3 UNION ALLSELECT 4, 'CATEGORY 400', 2 UNION ALLSELECT 5, 'CATEGORY 500', 4 UNION ALLSELECT 6, 'CATEGORY 600', 9 UNION ALLSELECT 7, 'CATEGORY 700', 8 UNION ALLSELECT 8, 'CATEGORY 800', 7 UNION ALLSELECT 9, 'CATEGORY 900', 6CREATE TABLE TBLORDERPROCESSING(IDNO INT PRIMARY KEY NOT NULL,ORDERPROCESSING VARCHAR(50))INSERT INTO TBLORDERPROCESSING (IDNO, ORDERPROCESSING)SELECT 1, 'ORDER PROCESSING A1' UNION ALLSELECT 2, 'ORDER PROCESSING A9' UNION ALLSELECT 3, 'ORDER PROCESSING Z5' UNION ALLSELECT 4, 'ORDER PROCESSING 76' UNION ALLSELECT 5, 'ORDER PROCESSING 98' UNION ALLSELECT 6, 'ORDER PROCESSING AB' UNION ALLSELECT 7, 'ORDER PROCESSING 11' UNION ALLSELECT 8, 'ORDER PROCESSING T7' UNION ALLSELECT 9, 'ORDER PROCESSING ZX'CREATE TABLE TBLSTATUS(IDNO INT PRIMARY KEY NOT NULL,STATUS VARCHAR(50),ORDERPROCESSINGNO INT)INSERT INTO TBLSTATUS (IDNO, STATUS, ORDERPROCESSINGNO)SELECT 1, 'ABC', 1 UNION ALLSELECT 2, 'DEF', 1 UNION ALLSELECT 3, 'GHI', 1 UNION ALLSELECT 4, 'JKL', 1 UNION ALLSELECT 5, 'MNO', 2 UNION ALLSELECT 6, 'PQR', 2 UNION ALLSELECT 7, 'STU', 3 UNION ALLSELECT 8, 'VWX', 3 UNION ALLSELECT 9, 'YZ', 3 UNION ALLSELECT 10, '123', 3 UNION ALLSELECT 11, '456', 3 UNION ALLSELECT 12, '789', 3 UNION ALLSELECT 13, '0AA', 3 UNION ALLSELECT 14, '0BB', 3 UNION ALLSELECT 15, '0CC', 5 UNION ALLSELECT 16, '0DD', 5 UNION ALLSELECT 17, '0EE', 5 UNION ALLSELECT 18, '0FF', 8 UNION ALLSELECT 19, '0GG', 8 UNION ALLSELECT 20, '0HH', 8 UNION ALLSELECT 21, '0II', 8 UNION ALLSELECT 22, '0JJ', 9 UNION ALLSELECT 23, '0KK', 9 UNION ALLSELECT 24, '0LL', 9 UNION ALLSELECT 25, '0MM', 9/*If you run the above, the data is CORRECT and the wayit normally should be.Basically, each Order is linked to an OrderTypeNo. EachOrderTypeNo is linked to an OrderProcessingNo.Each Order has MANY OrderStatuses. EachOrderProcessingNo has MANY Statuses.So both TBLORDERTYPE and TBLSTATUS is pointingto TBLORDERPROCESSING. I will mess up an Orderrecord for example to point to a wrong OrderType andleave its LASTSTATUSNO and all its CHILDTBLORDERSTATUSES STATUS records point tothe CORRECT ORDERPROCESSINGNO.*/UPDATE TBLORDERSET ORDERTYPENO = 3WHERE IDNO = 5 OR IDNO = 10/*So now both Order IDNO 5 & 10 are basically messedup as they are pointing to ORDERTYPENO 3 (i.e.ORDERPROCESSINGNO 3) whereas theirLASTSTATUSNO and all its TBLORDERSTATUSSTATUS records are pointing to .......ORDERPROCESSINGNO 5 & 9Now I will mess up both TBLORDER andTBLORDERDETAILS in order for my codeNOT to fix it since this I will have to deal anddecide what to correct manually.*/UPDATE TBLORDERSET ORDERTYPENO = 2, LASTSTATUSNO = 15WHERE IDNO = 8SELECT * FROM TBLORDERGOCREATE VIEW VIEW1-- This VIEW1 returns all TBLORDER records that have the problemASSELECT TBLORDER.IDNO, TBLORDER.ORDERTYPENO, TBLORDER.LASTSTATUSNOFROM TBLORDERINNER JOIN TBLORDERTYPE ON TBLORDER.ORDERTYPENO = TBLORDERTYPE.IDNOINNER JOIN TBLSTATUS ON TBLORDER.LASTSTATUSNO = TBLSTATUS.IDNOAND TBLORDERTYPE.ORDERPROCESSINGNO <> TBLSTATUS.ORDERPROCESSINGNOGOCREATE VIEW VIEW2-- This VIEW2 does a GROUP BY of all TBLORDER.IDNO &TBLSTATUS.ORDERPROCESSINGNOASSELECT TOP 100 PERCENT TBLORDER.IDNO, TBLSTATUS.ORDERPROCESSINGNOFROM TBLORDERSTATUSES INNER JOINTBLORDER ON TBLORDERSTATUSES.ORDERNO = TBLORDER.IDNOINNER JOINTBLSTATUS ON TBLORDERSTATUSES.STATUSNO =TBLSTATUS.IDNO INNER JOINVIEW1 ON TBLORDER.IDNO = VIEW1.IDNOGROUP BY TBLORDER.IDNO, TBLSTATUS.ORDERPROCESSINGNOORDER BY TBLORDER.IDNO, TBLSTATUS.ORDERPROCESSINGNOGOCREATE VIEW VIEW3-- This VIEW3 checks to see if TBLORDERSTATUS records have more than oneORDERPROCESSINGNOASSELECT IDNOFROM VIEW2GROUP BY IDNOHAVING (COUNT(*) > 1)GOCREATE TABLE TMPORDERS(IDNO INT,OLDORDERTYPENO INT,NEWORDERTYPENO INT,LASTSTATUSNO INT)INSERT INTO TMPORDERS (IDNO, OLDORDERTYPENO, LASTSTATUSNO)SELECT TBLORDER.IDNO, TBLORDER.ORDERTYPENO, TBLORDER.LASTSTATUSNOFROM TBLORDERINNER JOIN TBLORDERTYPE ON TBLORDER.ORDERTYPENO = TBLORDERTYPE.IDNOINNER JOIN TBLSTATUS ON TBLORDER.LASTSTATUSNO = TBLSTATUS.IDNOAND TBLORDERTYPE.ORDERPROCESSINGNO <> TBLSTATUS.ORDERPROCESSINGNOLEFT JOIN VIEW3 ON TBLORDER.IDNO = VIEW3.IDNO AND VIEW3.IDNO IS NULLSELECT * FROM TMPORDERSUPDATE TMPORDERSSET NEWORDERTYPENO = TBLORDERTYPE.IDNOFROM TBLORDERTYPEINNER JOIN TBLORDERPROCESSING ON TBLORDERTYPE.ORDERPROCESSINGNO =TBLORDERPROCESSING.IDNOINNER JOIN TBLSTATUS ON TBLORDERPROCESSING.IDNO =TBLSTATUS.ORDERPROCESSINGNOWHERE TBLSTATUS.IDNO = TMPORDERS.LASTSTATUSNOUPDATE TBLORDERSET ORDERTYPENO = NEWORDERTYPENOFROM TMPORDERSWHERE TMPORDERS.IDNO = TBLORDER.IDNOSELECT * FROM TBLORDER/*Is there a better to write my Update statement? As you can see thatI am using 3 views, 1 temp table and 2 update statements tofix my problem.I am not even sure if i'll need to add more update statementsto handle other corrections. If that is the case I am trying tosee if my code can be simplified in order for it to be easilymodifiable to handle other scenarios.Thank you for your time.*/
View 2 Replies
View Related