Avatar billede madssch Nybegynder
18. marts 2004 - 14:15 Der er 9 kommentarer og
2 løsninger

Slet referencer

Hej Eksperter!

Jeg er ved at lave et website hvor der er menupunkter i flere niveauer. Alle siderne ligger i den samme tabel, og er bundet op på hinanden med refId'er og Levels.

Sletter jeg f.eks. en side på Level1, skal den gerne automatisk slette alle underliggende sider til denne.

Dette kan gøres hvis disse ligger i forskellige tabeller, men kan det lade sig (automatisk) når de ligger i samme tabel?

Håber mit spørgsmål er forståeligt!

På forhånd tak!

;-)
Avatar billede zedios Nybegynder
18. marts 2004 - 14:36 #1
Du kan ikke umiddelbart godt definere en FK imellem forskellige kolonner på samme tabel (rekursiv relation), men du kan ikke sætte cascade update/delete på denne som du ellers nomalt ville kunne hvis det var mellem to tabeller du definere din FK constraint

En løsning kunne dog være at definere en trigger som sørgede for dette, men jeg ville personligt foretrække at bygge logikken ind i en Stored Procedure.

Det er en både pænere og mere læsevenlig løsning. Perfomance mæssigt vil den næsten helt sikkert også være bedre end en trigger ..
Avatar billede madssch Nybegynder
18. marts 2004 - 14:45 #2
Jeg er helt ny i MSSQL, så jeg har ikke stiftet nærmere bekendskab med hverken Stored Procedures eller Triggers.

Kan dette vises med et simpelt eksempel, eller er det mere kompliceret?
Avatar billede zedios Nybegynder
18. marts 2004 - 15:22 #3
Hvis du sender lidt om din tabel struktur samt info om opdaterings logikken så skulle det jo nok kunne lade sig gøre .o)
Avatar billede zedios Nybegynder
18. marts 2004 - 15:24 #4
PS: iøvrigt kan du kigge lidt i BOL under Stored Procedures, triggers, samt "INSTEAD OF INSERT Triggers" for info på begreberne ..
Avatar billede madssch Nybegynder
18. marts 2004 - 15:31 #5
Ok.

Side på niveau 1:

Titel: Menupunkt
Id: 1
refId: 0
[level]: 1

Side på niveau 2:

Titel: Sub til Menupunkt
Id: 2
refId: 1
[level]: 2

Kan du bruge dette til noget?
Avatar billede zedios Nybegynder
19. marts 2004 - 09:10 #6
Kunne forestille mig noget i denne stil med en Stored Procedure (SP):
(Husk det kun er reference kode og du må modificere den til dit endelige setup!)

CREATE PROCEDURE [dbo].[delMenuItem]
        @menuItemID INT

SET NOCOUNT ON
AS

DECLARE @refID INT

-- First get menu reference
-- I asume that one Id Only can have one refIdD!
SELECT @refId = [refId] FROM [dbo].[tblMenu] WHERE [Id] = @menuItemID

BEGIN TRANSACTION
    -- Now for the delete ..
    -- First delete sub menu items based on @refID
    DELETE FROM [dbo].[tblMenu] WHERE [refId] = @refId
    -- Then delete main menu item based on @menuItemID
    DELETE FROM [dbo].[tblMenu] WHERE [Id] = @menuItemID
-- Could place some error handling here ..
COMMIT TRANSACTION
Avatar billede madssch Nybegynder
19. marts 2004 - 09:41 #7
2 kommentarer:

1: I SP'en får jeg 2 syntaksfejl. En ved 'SET' og en ved 'AS'. Det er muligvis fordi jeg selv skal indsætte noget, eller..? Jeg har som sagt ikke stiftet bekendskab med SP's før.

2: Jeg synes at kunne gennemskue, at funktionen ikke gør det jeg ønsker. Den sletter den aktuelle side og dennes undersider - men da der er 3 levels kan der i reliteten hænge en side på level 3 som ikke bliver slettet. Er det forståeligt?
Avatar billede zedios Nybegynder
19. marts 2004 - 10:05 #8
Ups ..

der skal byttes om på "SET NOCOUNT ON" og "AS" - sorry ..

CREATE PROCEDURE [dbo].[delMenuItem]
        @menuItemID INT

AS
SET NOCOUNT ON

DECLARE @refID INT

...
Avatar billede zedios Nybegynder
19. marts 2004 - 10:07 #9
Prøv at poste tabel indhold for det aktuelle eksempel - det er  nemmere at kode ud fra ..
Avatar billede madssch Nybegynder
19. marts 2004 - 10:51 #10
Jeg har midlertidigt fundet et alternativ.

Jeg har udviklet en rekursiv funktion, som kan gøre jobbet for mig:

intPageId = Request.QueryString("pageId")

Set Query = objConnect.Execute("Select pageId, pageRefId, title from pages Where languageId = "& intLanguageId &"")

Do until Query.EOF

    arrPageId = arrPageId & "," & Query("pageId")
    arrPageRefId = arrPageRefId & "," & Query("pageRefId")
    arrPageTitle = arrPageTitle & "," & Query("title")

Query.MoveNext
Loop

Set Query = Nothing


arrPageId = Split(arrPageId,",")
arrPageRefId = Split(arrPageRefId,",")
arrPageTitle = Split(arrPageTitle,",")


Function deletePages(pageId)

    For i = 1 to Ubound(arrPageId)

        If Cint(arrPageRefId(i)) = Cint(pageId) Then

            Set Query_delete = objConnect.Execute("Delete From pages Where pageId = " & arrPageId(i) & "")
            Set Query_delete = Nothing
           
            deletePages(arrPageId(i))

        End If

    Next

End Function


Response.Write deletePages(intPageId)


Set Query_delete = objConnect.Execute("Delete From pages Where pageId = " & intPageId & "")
Set Query_delete = Nothing

Response.Redirect "list_pages.asp?" & Replace(Session("qString"), "&", "&")

Med tiden kan funktionen muligvis flyttes over i SQL-serveren for optimering - men indtil videre ser jeg problemet som løst.

Du skal selvfølgelig have tak for hjælpen - og får points for ulejligheden!

;-)
Avatar billede zedios Nybegynder
19. marts 2004 - 12:22 #11
Takker! Havde faktisk mistanke om at der var tale omm et recursivt hieraki, men det var bare ikke lige til at se ud fra de data du sendte første gang ..
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
Computerworld tilbyder specialiserede kurser i database-management

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