sql >> Database teknologi >  >> RDS >> Sqlserver

En fleksibel fremmednøgle

En måde at løse det på ville være at tilføje en tabel til din database for at fungere som en base for de andre tabeller og forbinde den med en en til en relation til de andre tabeller og derefter forbinde begivenhedstabellen til denne basistabel.
Dette vil give dig mulighed for at bevare dataintegriteten for hver af tabellerne.
Basistabellen kan være så simpel som kun én kolonne, eller den kan have kolonner, som alle andre tabeller har til fælles, og dermed implementere en slags " arv" i din datastruktur.

Opret basistabellen (forudsat ingen fælles kolonner mellem andre tabeller):

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

Derefter for enhver anden tabel, der skal refereres af ObjectId i Events tabel:

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)
)

Det eneste, der er tilbage, er at indsætte en ny værdi til TblObjectBase for enhver indsættelse på dine andre tabeller. Dette kan nemt opnås ved enten lagrede procedurer eller i stedet for indsættelsesudløsere.
En indsættelsesprocedure kunne se sådan ud:

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...)

En i stedet for indsæt trigger ville se sådan ud:

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

Hvis du vælger at gå med i stedet for at indsætte, bør det faktum, at Identity-værdien kommer fra en anden tabel, være gennemsigtigt for klienten (dit vb.net-program).



  1. Hvordan kan jeg lave fatale fejl i ALLE mysql-advarsler?

  2. PostgreSQL - Omdøb database

  3. Sådan fungerer MapReduce i Hadoop

  4. Mysql:Vælg alle data mellem to datoer