Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Une clé étrangère flexible

Une façon de le résoudre serait d'ajouter une table à votre base de données pour agir comme une base pour les autres tables et de la connecter avec une relation un à un avec les autres tables, puis de connecter la table des événements à cette table de base.
Cela vous permettra de conserver l'intégrité des données pour chacune des tables.
La table de base peut être aussi simple qu'une seule colonne, ou peut avoir des colonnes que toutes les autres tables ont en commun, implémentant ainsi une sorte de " héritage" dans votre structure de données.

Créez la table de base (en supposant qu'il n'y a pas de colonnes communes entre les autres tables) :

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

Ensuite, pour toute autre table qui doit être référencée par le ObjectId dans les Events tableau :

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

La seule chose qui reste est d'insérer une nouvelle valeur dans la TblObjectBase pour toute insertion sur vos autres tables. Cela peut être facilement réalisé soit par des procédures stockées, soit à la place de déclencheurs d'insertion.
Une procédure d'insertion pourrait ressembler à ceci :

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

Un déclencheur au lieu d'insérer ressemblerait à ceci :

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

Si vous choisissez d'utiliser le au lieu d'insérer, le fait que la valeur Identity provienne d'une autre table doit être transparent pour le client (votre programme vb.net).