Avatar billede kasseper Nybegynder
30. oktober 2002 - 12:16 Der er 13 kommentarer og
1 løsning

Delete SQL , loops, mappe struktur

Nestede løkker, rekursivitet, SQL, eller hårdt arbejde...
Det er et par af de spørgsmål som jeg står med..hmmm som man siger: first things first !

Jeg har en tabel i en ACCESS database( kaldte jeg virkelig det for en database ????, Ok men det er det vel så ) Tabellen hedder Mapper og har tre felter :
MappeID, navn og Parent.
Denne tabel skal alene simulere et Mappe hieraki, som vi kender det fra windows stifinderen. Altså ikke noget med filer kun mapper(eller biblioteker eller folders, who cares ). Parent er således en reference til en anden rows mappeID i samme tabel. Den listige har nok regnet ud at jeg bruger det til en TreeView control. Jeg har ingen problemer med at oprette mapper og initielt generere mit mappe hieraki, men problemet kommer når jeg skal slette en mappe og ALLE den under mapper.
Jeg tænkte først at det ikke var noget problem, jeg laver bare en rekursiv funktion der sletter helt ned i nederste niveau først også op efter indtil rodmappen nåes. Men det betyder en hulens masse DELETE statements der blir fyret af. Desvære kan man i ACCESS ikke oprette en sådan afhængighed til sig selv, og dermed opnå kaskadevis sletning af posterne....!
Men det jeg så gerne vil ha jer til er at finde den optimale løsning, og hvis i ikke kan det, så bare en løsning :
Optimal løsning : En motherfucker af en SQL sætning der klare ærterne i et hug.
Alternativ løsning : en funktion i Vb, som løser problemet på den ene eller den anden måde.

Kom så Gutter og Gut'inder gang i cellerne
Tak !
Avatar billede Spotgun Seniormester
30. oktober 2002 - 12:41 #1
Det er sgu meget interessant - sidder med en lignende problemstilling selv. Løsningen med bunkevis af SQL-statements er jeg heller ikke specielt glad for, og har pønset på et utal af alternativer, uden at blive specielt meget klogere...

Det må kunne la' sig gøre, uden at spamme databasen med SQL-kald!
Avatar billede di8leva Nybegynder
30. oktober 2002 - 12:52 #2
Jag har ett liknande tree, och jag anvænder føljande kod:

ResultSet rs = database.execute("delete from Mapper where MappeId = " + id + "; select MappeId from Mapper where parentId = " + id + ";");
while(rs.next())
    delete(rs.getInt("mappeId"));

dær delete ær en rekursiv funktion som gør samma sak
det blir en hel del deletes, men det går stadvek hurtigt och utan problemer...
Avatar billede kasseper Nybegynder
30. oktober 2002 - 13:11 #3
di8leva >> Jeg kan se at du har valgt den alternative løsning, men det er også cool nok, men kan du ikke paste hele koden, også den rekursive funktion delete ?
Jeg lader spørgsmålet stå åbent lidt mere tid, for at se om der skulle komme en med den optimale løsning !
Avatar billede di8leva Nybegynder
30. oktober 2002 - 13:18 #4
hehe, funktionen er ikke i VB, den er i Java, men tanken ær densamme
Avatar billede kasseper Nybegynder
30. oktober 2002 - 13:22 #5
Det er cool, jeg er selv Java programør, så det er ikke noget problem at oversætte den !
Avatar billede di8leva Nybegynder
30. oktober 2002 - 13:39 #6
here goes....

    private void remove(int id) throws SQLException
    {
        DatabaseClient dbclient = DatabaseClient.getClient();
        try
        {
            dbclient.setSQL("delete from mapper where mappeId= " + id+ "; select mappeId from mapper where parent = " + id);
            ResultSet rs = dbclient.getResultSet();
            while(rs.next())
                remove(rs.getInt(1));
        }
        finally
        {
            dbclient.close();
        }
    }
Avatar billede di8leva Nybegynder
30. oktober 2002 - 13:40 #7
rekursivt och fint =)
men måske finns der effektivere måder att gøra det på.... jag har inte kommit på några
Avatar billede kennethrisum Nybegynder
31. oktober 2002 - 21:11 #8
Hvis du har det hele læst ind i et recordset (rs i eksemplet) kan du bruge:

function DeleteSQL(sql as String, id as long)
  sql = sql & " (MappeID = " & cstr(id) & ") OR "
  rs.filter="parent = " & cstr(id)
Avatar billede kennethrisum Nybegynder
31. oktober 2002 - 21:16 #9
sorry!

Jeg kom til at trykke på 'Udfør' for hurtigt. Men idéen er, at du opbygger din where clause i en rekursiv funktion. Herefter bruger du bare:

Dim s as string
db.execute "Delete from tabel where " & DeleteSQL(s,MappeID)

Håber du kan se idéen ;-)
Avatar billede kasseper Nybegynder
01. november 2002 - 07:38 #10
kennethrisum >> Hmmmm. kan du ikke lige forklare hvad du mener med det hele i recordset'et ?
Avatar billede kennethrisum Nybegynder
01. november 2002 - 09:22 #11
Jeg mener:
du har åbnet et recordset, der indeholder samtlige data fra tabellen.
Bruger du ADO eller DAO til at hente data?
Avatar billede kasseper Nybegynder
01. november 2002 - 09:32 #12
ADO
Avatar billede kennethrisum Nybegynder
01. november 2002 - 16:46 #13
Hvis du bruger client side cursors, har du hele recordset'et i hukommelsen. Så ud fra dette recordset kan du lave en rekursiv funktion, der genererer din where clause (skrevet i mere eller midnre pseudo kode):

function DeleteSQL(sql as String, id as long)
  sql = sql & " (MappeID = " & cstr(id) & ") OR "
  rs.filter=""
  rs.filter="parent = " & cstr(id)
  Do while rs.eof = false
    call deletesql(sql,rs.fields("MappeID").value
    rs.movenext
  loop
  deletesql=sql
end function

Jeg har ikke lige VB på denne pc, men princippet virker. rs er det recordset, som du har dine data i. Du kan evt. sætte den som en parameter i funktionen.

Du kalder så:

Dim s as string
connection.execute "Delete from tabel where " & DeleteSQL(s,MappeID)

Bagefter laver du en requery på dit recordset. Jeg kan godt lave koden til dig, men så bliver det tidligst søndag aften.
Avatar billede kasseper Nybegynder
08. november 2002 - 10:00 #14
det virker kennethrisum tak
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB

Capgemini Danmark A/S

Open Application (Denmark)

Riskpoint A/S (Riskpoint Solutions Limited)

Senior Developer