none
1:1-Beziehung - Datensätze automatisch anlegen? RRS feed

  • Frage

  • Hallo,

    ich habe eine Tabelle und dazu eine Detailtabelle alös 1:1-Beziehung:

    create table person
    (
     idx int,
     name varchar(50),
     ...
     primary key(idx)
    );
    
    create table person_details
    (
     idx int,
     data varchar(50),
     ...
     primary key(idx),
     foreign key (idx) references person(idx)
    );

    Ich möchte sicherstellen, dass es zu jedem Datensatz in person auch immer einen Datensatz in person_details gibt.

    Dass letzterer mit gelöscht wird, wenn ersterer gelöscht wird, kann ich ja mit "on delete cascade" sicherstellen, oder?

    Aber wie stelle ich sicher, dass bei einem neuen Datensatz in person automatisch einer in person_detail erstellt wird?

    Braucht es dazu einen Trigger oder gibt es dazu auch eine Direktive wie die oben?

    Danke

    Magnus

    Dienstag, 7. Juli 2015 06:27

Antworten

  • Hallo Markus,
    das müsstest Du schon über einen Trigger machen.

    Ich frage mich nur, welchen Sinn macht dieses Tabelle mit den Details, wenn sie immer gefüllt sein muss und der Primary Key dem Primary Key der Personen entspricht.
    Warum also nicht direkt alles in eine Tabelle schreiben?

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Dienstag, 7. Juli 2015 06:46
  • Hallo Magnus

    Nein einen Trigger muss man hier nicht nutzen. Du kannst dir hier zwei gespeicherte Prozeduren erstellen welche die Daten zusammen eintragen und auch wieder löschen. Hier kannst du dann über eine explizite Transaktion sagen dass nur zusammen eingetragen werden soll.

    Vom Grundsatz würde es dann ungefär so aussehen

    CREATE PROCEDURE InsertPerson 
        @LastName nvarchar(50), 
        @FirstName nvarchar(50),
        -- und andere Werte für das Insert
    AS 
      
    BEGIN TRY    
      BEGIN TRANSACTION
    
         insert into personen --was auch immer
         insert into personen.details  --was auch immer
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSATION
    END CATCH 
    GO

    Und genau so dann auch für das Löschen der Datensätze. Zum einfügen der Werte dann einfach die Prozedur mit den Werten ausführen lassen. Vorteil ist auch dass du gut Fehlerprüfungen einbauen kannst.

    Gruß Benjamin


    Benjamin Hoch
    MCSA: Microsoft Certified Solutions Associate - SQL Server 2012,
    MCSA: Microsoft Certified Solutions Associate - Windows Server 2012,

    Dienstag, 7. Juli 2015 07:01

Alle Antworten

  • Hallo Markus,
    das müsstest Du schon über einen Trigger machen.

    Ich frage mich nur, welchen Sinn macht dieses Tabelle mit den Details, wenn sie immer gefüllt sein muss und der Primary Key dem Primary Key der Personen entspricht.
    Warum also nicht direkt alles in eine Tabelle schreiben?

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Dienstag, 7. Juli 2015 06:46
  • Hallo Magnus

    Nein einen Trigger muss man hier nicht nutzen. Du kannst dir hier zwei gespeicherte Prozeduren erstellen welche die Daten zusammen eintragen und auch wieder löschen. Hier kannst du dann über eine explizite Transaktion sagen dass nur zusammen eingetragen werden soll.

    Vom Grundsatz würde es dann ungefär so aussehen

    CREATE PROCEDURE InsertPerson 
        @LastName nvarchar(50), 
        @FirstName nvarchar(50),
        -- und andere Werte für das Insert
    AS 
      
    BEGIN TRY    
      BEGIN TRANSACTION
    
         insert into personen --was auch immer
         insert into personen.details  --was auch immer
        COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSATION
    END CATCH 
    GO

    Und genau so dann auch für das Löschen der Datensätze. Zum einfügen der Werte dann einfach die Prozedur mit den Werten ausführen lassen. Vorteil ist auch dass du gut Fehlerprüfungen einbauen kannst.

    Gruß Benjamin


    Benjamin Hoch
    MCSA: Microsoft Certified Solutions Associate - SQL Server 2012,
    MCSA: Microsoft Certified Solutions Associate - Windows Server 2012,

    Dienstag, 7. Juli 2015 07:01
  • Die Frage lautete aber "Ich möchte sicherstellen ..." .
    Bei Verwendung der Prozedur mag es sichergestellt sein, aber an der Prozedur vorbei kann man weiterhin machen, was man möchte.
    Just my 2 cents.

    Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    Dienstag, 7. Juli 2015 07:34
  • Hallo Christoph,

    dann könnte man noch die DML Reche auf die Tabellen so einschränken dass nur noch die Prozeduren dieses Recht haben und hier dann ggf. mit "execute as " arbeiten. Somit wäre der Weg an den Prozeduren vorbei auch gesichert.

    Gruß Benjamin


    Benjamin Hoch
    MCSA: Microsoft Certified Solutions Associate - SQL Server 2012,
    MCSA: Microsoft Certified Solutions Associate - Windows Server 2012,

    Dienstag, 7. Juli 2015 08:32