10. marts 2007 - 19:06Der er
9 kommentarer og 1 løsning
En avanceret UPDATE ?
Vi har en tabel (TREE) i vores database som beskriver en træstruktur. ID er unik identifikation af hver mappe i træstrukturen, Father_ID angiver hvilken mappe hver mappe har som forældre i strukturen. De mapper som ligger på øverste niveau har Father_ID=0. Hver mappe har også et navn.
Opgaven er nu at skrive en SQL sætning (eller flere) som sørger for at mapperne i andet niveau alle får udskiftet første tre tegn af deres navn så det svarer til første del af navnet i den overliggende mappe (dvs. fra deres father). I eksemplet neden for skal f.eks. ID 6,7 og 8 alle have uskiftet 01. med 02 i deres navn. Der er kun to nivauer i træstrukturen, dvs. yderste niveau (med Father_ID=0) og så de samme undermapper til hver. Alle disse undermapper skal altså omdøbes så starten af deres navn afspejler tallet angivet i overmappen.
Vores løsning er indtil videre at skrive en bunke SQL sætninger der hver for sig klarer indholdet i en overordnet mappe:
UPDATE tree SET navn = '02.' + substring(navn,4,100) WHERE Father_ID = 5 UPDATE tree SET navn = '03.' + substring(navn,4,100) WHERE Father_ID = 9 osv.
Jeg drømmer dog om at finde en måde hvor vi kunne skrive en super SQL statement som kunne klare det hele i et hug .. måske ved inde i UPDATEN sørge for at der er en select som udtrækker det nødvendige fra father, eller noget .. men er gået lidt kold på dette.
Er der nogen der har en ide til om og hvordan dette kunne gøres? På forhånd tak
Måske noget i denne stil: declare @minID int, @maxID int SELECT @minID= min(id), @maxID=max(id) FROM TREE WHERE Father_ID=0 WHILE @minID<=@maxID BEGIN
UPDATE t SET t.Navn=substring(tParent.navn,0,2)+''+substring(T.navn,2,100) FROM Tree T JOIN Tree tParent ON tParent.ID = T.Father_ID WHERE T.Father_ID=@minID
SELECT @minID= min(id)FROM TREE WHERE Father_ID=0 AND id>@minID END
måske endda: UPDATE t SET t.Navn=substring(tParent.navn,0,3)+''+substring(T.navn,2,100) FROM Tree T JOIN Tree tParent ON tParent.ID = T.Father_ID WHERE T.Father_ID=0
Takker, det må jeg lige studere .. Vi sidder med et SQL interface direkte i applikationen som kun tillader at man udfører en SQL sætning af gangen interaktivt, jeg er ikke sikker på at den håndterer declare af lokale variable - men det må jeg undersøge.
Der hvor du skriver måske endda .. er det skud på en SQL sætning der klarer det hele? Jeg må lige se nærmere på den.
Jeg har nu været logget på vores database, fundet de rigtige tabel og kononnenavn (så de ikke længere blot er fra hukommelsen) og testet dit andet forslag. Underligt nok uden at den ændrer navnene...
Her først lige dataeksemplet igen med de korrekte kollonnenavne:
UPDATE t set t.cf_item_name=substring(tParent.cf_item_name,1,3)+substring(t.cf_item_name,4,100) FROM cycl_fold t join cycl_fold tParent ON tParent.cf_item_id = t.cf_father_id where t.cf_father_id=0
Gav som sagt ikke noget resultet (dvs. helt tomt) !?
Hvis jeg lige tester med en select så giver følgende et helt tomt resultat:
select * from cycl_fold t join cycl_fold tParent ON tParent.cf_item_id=t.cf_father_id where t.cf_father_id=0
Kan det måske være noget med at det skal være en inner (eller outer) join eller sådan noget istedet (og hvordan er det nu man skriver det)?
Tak indtil videre, jeg er sikker på at vi er på rette spor :-)
Det var noget jeg lavede ud fra hovedet så jeg kan godt forstå at jeg ikke rammer helt rigtigt :)
Det er mig som har vendt den lidt forkert, prøv lige med: select * from cycl_fold t join cycl_fold tParent ON tParent.cf_item_id=t.cf_father_id where t.cf_father_id>0
Hvis den virker så burde det rigtige være: UPDATE t set t.cf_item_name=substring(tParent.cf_item_name,1,3)+substring(t.cf_item_name,4,100) FROM cycl_fold t join cycl_fold tParent ON tParent.cf_item_id = t.cf_father_id where t.cf_father_id>0
Åh ja, det burde jeg have set, faktisk havde jeg i mine eksprimenter med selecten på et tidspunkt tænkt på >0 og prøvet det, men af en eller anden grund forventede jeg ikke at få de rækker, men det var så det rigigte alligevel ... den virker! Det er dog utroligt at du sådan lige kan lide det af ud fra hovedet :-) Tusind tak for hjælpen.
Læg venligst et 'svar' så jeg kan give dig nogle point.
Man kan kun sige at erfaring ikke er en dårlig ting :) svar :)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.