none
Trigger Aber wie? RRS feed

  • Frage

  • Hallo zusammen,

    mich beschleicht so langsam Panik. Ich weiss nicht wie das zu lösen ist.

    Zu einer Tabelle habe ich einen Trigger erstellt. Mit dem ich den Tabellennamen und die IDs der gelöschten Tabellen festhalten möchte.
    Mir scheint das es funktioniert, wenn nur ein Record gelöscht wird, aber nicht wenn mehrere records gelöscht werden.

    Als Fehlermeldung erhalte ich:
    Meldung 512, Ebene 16, Status 1, Prozedur ZeitDelete_SummeKostenProjektUserGroup, Zeile 21
    Die Unterabfrage hat mehr als einen Wert zurückgegeben. Das ist nicht zulässig, wenn die Unterabfrage auf =, !=, <, <=, > oder >= folgt oder als Ausdruck verwendet wird.

    Jetzt vermute/interpretiere ich, es liegt an der Zeile "SELECT idUserProjektFilter FROM deleted", falls durch das löschen mehr als eine Zeile betroffen ist.
    Aber wie lösst man das Problem.

     

    USE

    [RubZRF]
    GO
    SET ANSI_NULLS

    ON
    GO

    SET

    QUOTED_IDENTIFIER

    ON
    GO

    ALTER

    TRIGGER [dbo].[Delete_tabBenutzerProjektFilter] ON [dbo].

    [tabBenutzerProjektFilter]

    AFTER

    DELETE
    AS
    BEGIN

    SET

    NOCOUNT ON

    ;

    Declare

    @ID as

    uniqueidentifier

    SET

    @ID = (SELECT idBenutzerProjektFilter FROM deleted

    )

    INSERT

    INTO [RubagZRF].[dbo].[tabGrabstein] ([id],[TabellenName],[idTabelle])
    VALUES (newid(),'tabBenutzerProjektFilter',@ID

    )

     

    END

     

    Grüsse Peter

     

     


    Peter
    Mittwoch, 25. Mai 2011 13:02

Antworten

  • hi,

    deine Ansatz ist richtig, du liest ja schon genau eine ID aus der Pseudeotabelle DELETED. Aber da es eine Tabelle ist und er der Trigger per Statement ausgeführt wird, schlägt es genau dort fehl. Du musst es nur auf einen mengenbasierten Ansatz umbauen, z.B.

    ALTER TRIGGER [dbo].[Delete_tabBenutzerProjektFilter] ON [dbo].[tabBenutzerProjektFilter]
        AFTER DELETE
    AS
    BEGIN
        SET NOCOUNT ON ;
    
        INSERT  INTO [RubagZRF].[dbo].[tabGrabstein]
                ( [id] ,
                  [TabellenName] ,
                  [idTabelle]
                )
                SELECT  NEWID() ,
                        'tabBenutzerProjektFilter' ,
                        idBenutzerProjektFilter
                FROM    deleted ;
    END ;

    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    • Als Antwort markiert peter haus Mittwoch, 25. Mai 2011 14:50
    Mittwoch, 25. Mai 2011 13:47
    Moderator

Alle Antworten

  • hi,

    deine Ansatz ist richtig, du liest ja schon genau eine ID aus der Pseudeotabelle DELETED. Aber da es eine Tabelle ist und er der Trigger per Statement ausgeführt wird, schlägt es genau dort fehl. Du musst es nur auf einen mengenbasierten Ansatz umbauen, z.B.

    ALTER TRIGGER [dbo].[Delete_tabBenutzerProjektFilter] ON [dbo].[tabBenutzerProjektFilter]
        AFTER DELETE
    AS
    BEGIN
        SET NOCOUNT ON ;
    
        INSERT  INTO [RubagZRF].[dbo].[tabGrabstein]
                ( [id] ,
                  [TabellenName] ,
                  [idTabelle]
                )
                SELECT  NEWID() ,
                        'tabBenutzerProjektFilter' ,
                        idBenutzerProjektFilter
                FROM    deleted ;
    END ;

    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    • Als Antwort markiert peter haus Mittwoch, 25. Mai 2011 14:50
    Mittwoch, 25. Mai 2011 13:47
    Moderator
  • Hi Stefan,

    vielen Dank. In SQL sind meine Lücken Gross.

    Ist es so einfach!?
    Wird bei Deiner Lösung schon über alle gelöschten Records iteriert?

    Grüsse Peter

     


    Peter
    Mittwoch, 25. Mai 2011 14:23
  • hallo Peter,

    Ist es so einfach!?

    Ja :)

    Wird bei Deiner Lösung schon über alle gelöschten Records iteriert?

    Im strengen Sinne des Wortes 'iteriert' lautet die Antwort: Nein. Lies dir mal die Hilfe zu den Pseudeotabellen DELETED und INSERTED durch.

    In DELETED sind alle gelöschten Datensätze enthalten. Es ist eine Tabelle. Damit liefert SELECT id FROM DELETED alle gelöschten IDs. Diese Abfrage wird einfach als Eingabe für das INSERT INTO benutzt.

    Es wird hier aus der Menge der gelöschten Daten eine zu deiner Protokolltabelle passsende Menge projiziert und eingefügt. Es ist eine Mengenoperation. Daher keine Iteration.


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Mittwoch, 25. Mai 2011 14:36
    Moderator
  • Hallo Stefan,

    es funktioniert. Vielen Dank.


    >Es ist eine Tabelle. Damit liefert SELECT id FROM DELETED alle gelöschten IDs.
    Mit dem Umstand, hatte ich einen Knoten im Hirn.

    Gruss Peter


    Ich war ganz darin versteift, das das ganze Statement (Insert To) in eine "Schleife" muss,
    nicht nur der Teil ,der die Werte entgegen nimmt.

    Mittwoch, 25. Mai 2011 14:50