sql >> Database >  >> RDS >> Sqlserver

Een flexibele buitenlandse sleutel

Een manier om dit op te lossen zou zijn om een ​​tabel aan uw database toe te voegen om als basis voor de andere tabellen te fungeren en deze te verbinden met een één-op-één relatie met de andere tabellen, en vervolgens de gebeurtenissentabel te verbinden met deze basistabel.
Hierdoor kunt u de gegevensintegriteit voor elk van de tabellen behouden.
De basistabel kan zo eenvoudig zijn als slechts één kolom, of kan kolommen hebben die alle andere tabellen gemeen hebben, waardoor een soort van " overerving" in uw gegevensstructuur.

Maak de basistabel (ervan uitgaande dat er geen gemeenschappelijke kolommen tussen andere tabellen zijn):

CREATE TABLE TblObjectBase 
(
    ObjectBase_Id int IDENTITY(1,1) PRIMARY KEY
)

Dan, voor elke andere tabel waarnaar moet worden verwezen door de ObjectId in de Events tafel:

CREATE TABLE TblClients 
(
    Client_Id int PRIMARY KEY,
    Client_FirstName varchar(10),
    Client_LastName varchar(10),
    --  Other client related data
    CONSTRAINT FK_TblClients_TblObjectBase
               FOREIGN KEY(Client_Id) 
               REFERENCES TblObjectBase(ObjectBase_Id)
)

CREATE TABLE TblInvoices
(
    Invoice_Id int PRIMARY KEY,
    -- other incoice related data
     CONSTRAINT FK_TblInvoices_TblObjectBase
               FOREIGN KEY(Invoice_Id) 
               REFERENCES TblObjectBase(ObjectBase_Id)
)

Het enige dat overblijft is om een ​​nieuwe waarde in de TblObjectBase in te voegen voor elke invoeging op uw andere tabellen. Dit kan eenvoudig worden bereikt door middel van opgeslagen procedures of in plaats van invoegtriggers.
Een invoegprocedure kan er als volgt uitzien:

CREATE PROCEDURE Insert_TblClients
(
    @Client_FirstName varchar(10),
    @Client_LastName varchar(10),
    -- any other client related data you might have
)
AS
DECLARE @ClientId int

-- Insert a new record to the base table:
INSERT INTO TblObjectBase DEFAULT VALUES;

-- Get the id you've just inserted:
SELECT @ClientId = SCOPE_IDENTITY();

-- Insert the data to the clients table:
INSERT INTO TblClients 
(Client_Id, Client_FirstName, Client_LastName.....) VALUES
(@ClientId, @Client_FirstName, @Client_LastName...)

Een trigger in plaats van invoegen zou er als volgt uitzien:

CREATE TRIGGER TblClients_IO_Insert ON TblClients INSTEAD OF INSERT 
AS
BEGIN

DECLARE @ClientId int

-- Insert a new record to the base table:
INSERT INTO TblObjectBase DEFAULT VALUES;

-- Get the id you've just inserted:
SELECT @ClientId = SCOPE_IDENTITY();

INSERT INTO TblClients 
(Client_Id, Client_FirstName, Client_LastName.....) 
SELECT @ClientId, Client_FirstName, Client_LastName..... 
FROM inserted

END

Als u ervoor kiest om te gaan met de in plaats van invoeging, moet het feit dat de identiteitswaarde uit een andere tabel komt, transparant zijn voor de klant (uw vb.net-programma).



  1. MySQL-groepering per week, op basis van een datumkolom?

  2. Compressie en de effecten ervan op de prestaties

  3. PostgreSQL converteert array geretourneerd van functie naar kolommen

  4. Een CTE maken in Oracle