13. december 2007 - 08:54Der er
5 kommentarer og 1 løsning
rekursiv SQL og joins
Hej...
Jeg har en situation hvor jeg evt. kan bruge noget rekursivt SQL, har læst lidt om at det skulle kunne gøres, men de eksempler jeg har fundet er med en tabel der har en row der heder parrent. så det er lidt for enkelt i forhold til min situation.
Jeg har teknisk set 3 tabeller, kan måske undlade det 3. men det er lidt usikkert nu.
Jeg har nogle Objecter, objeckterne selv er lagret i en tabel med informationer om hvor det hører hjemme i en fil/mappe lignende struktur lad os kalde den tabel "O" for objekt.
Da man ikke direkte kan arbejde på objekter, tager man en kobi før dette gøres, når man har arbejdet færdig smider man så den kopi ind istedet for den originale, men da deres unikke ID bliver exponeret i nogle views til en aprtner, har vi brug for at bibeholde samme id, det er løst ved at have en tabel til at styre dette som Referere objecter ved et overordnet id, den tabel kalder vi "I" for identitet.
Sidst kan objekter arrangeres i et træ, det gøres ved en hjælpetabel der "kæder" dem sammen, tabellen har lidt yderligere informationer om relasionen som hvornår den blev lavet osv, derfor en tabel seperat til det, lad os kalde den sidste tabel "R" for relasion.
Så vi har: "O" : objekter "I" : identitet "R" : relasion
I indeholder 2 ting. en unik Identitet og en FK til O id... så: "I" ("I.id", "I.oid")
O har naturligvis et ID og så et tilhørsforhold (mappe id) "O" ("O.oid", "O.mid")
R har så en parrent ("O/I.oid") og en child ("I.id") "R" ("R.oid", "R.id")
Ok... jeg har prøvet at holde tingene så simple som muligt i forhold til hvad jeg har brug for, lidt en lang historie men håber det går, og at det ikke skræmmer folk væk.
Nu vil jeg så gerne have et flat view at alle objekter i en træstruktur ud fra et specifikt objekt id... og det tænkte jeg at jeg kunne bruge det her rekursive SQL til...
Tabellen "O" kan måske undlades, ved ikke helt om jeg får brug for at udvælge noget i den ud fra "O.mid", derfor er den lige med... Joins kommer jo så ind da det er "R" der linker objekter sammen.
Hej, 1) Hvis du har en "normal" tabel kan du bruge CONNECT BY PRIOR syntaksen i en normal SQL SELECT for at traversere og vise indholdet i en tabel i en træstruktur. Nu har du flere tabeller og ikke mindst objekter. Det er mange år siden jeg har brugt syntaksen selv, men jeg vil tro at du ikke kan bruge det p.g.a. dine objekter. Søg på CONNECT BY i SQL dokumentationen. 2) Du kan lave en PL/SQL TABLE FUNCTION hvor du selv looper etc. igennem data som du vil og returnerer én række af gangen i det format du vil. Denne TABLE FUNCTION kan du så bruge fra e.g. et view eller et SELECT statement. Søg i PL/SQL dokumentationen (eller google) efter TABLE FUNCTION eller PIPELINED.
WITH nodes AS ( SELECT I.id AS i_id, I.oid AS i_oid, R.oid AS parrent, R.id AS child_id FROM I LEFT OUTER JOIN R ON I.oid = R.oid ) SELECT i_id, i_oid, parrent, child_idFROM nodes CONNECT BY PRIOR i_id = child_id START WITH child_id IS NULL;
Så langt så godt, overstående spytter da et eller andet ud, om det er korrekt er jeg lidt langt fra at kunne se, desuden så skal der stadig kreterier ind... dog tror jeg at jeg fik fat i essensen af det han havde gang i.
WITH nodes as ( SELECT I.id as i_id, I.oid as i_oid, O.name as name, O.mid as mid, R.oid as r_oid, R.id as child_id FROM I INNER JOIN O ON O.oid = I.oid LEFT OUTER JOIN FITS ON I.oid = R.oid ) SELECT UNIQUE i_id, i_oid, name, mid FROM nodes START WITH i_id = 1 --(Indsæt Kriterie id) CONNECT BY PRIOR child_id = i_id;
Og det ser ud til at virke... (Puha)... Er ikke helt med på hvorfor eksempler der ude ikke benytter Unique mens jeg til syneladende har brug for det for ikke at få dupeletter, men der er måske noget grouping eller andet jeg har overset...
Men so far så ser det ud til at give et korrekt resultat...
Nå ja... fik da SQL'en til at virke efter ønske i sidste ende...
Næste problem er at OracleClient ser ud til at hoste op over den Query... så kom da kun til det næste problem... men lukker her da SQL i det mindste er på plads (også på flere afprøvede måder nu)...
Så hvis du lige ligger et svar så får du lige lidt af points, da jeg...
a. Må indrømme at jeg stadig slet ikke har afprøvet, eller overvejet at kigge på (2). b. Og at (1) jo var lidt hen af det rigtige (selv om jeg jo godt viste det på daværende tidspunkt, men stod der jo ikke lige frem nogen steder i spørgsmålet...
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.