sql >> Base de Datos >  >> RDS >> Sqlserver

Una clave externa flexible

Una forma de resolverlo sería agregar una tabla a su base de datos para que actúe como una base para las otras tablas y conectarla con una relación de uno a uno con las otras tablas, y luego conectar la tabla de eventos a esta tabla base.
Esto le permitirá mantener la integridad de los datos para cada una de las tablas.
La tabla base puede ser tan simple como una sola columna, o puede tener columnas que todas las demás tablas tienen en común, implementando así una especie de " herencia" en su estructura de datos.

Cree la tabla base (suponiendo que no haya columnas comunes entre otras tablas):

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

Luego, para cualquier otra tabla que deba ser referenciada por el ObjectId en los Events tabla:

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

Lo único que queda es insertar un nuevo valor en TblObjectBase para cualquier inserción en sus otras tablas. Esto se puede lograr fácilmente mediante procedimientos almacenados o en lugar de activadores de inserción.
Un procedimiento de inserción podría verse así:

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 disparador en lugar de insertar se vería así:

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 elige ir con el en lugar de insertar, el hecho de que el valor de Identidad provenga de otra tabla debe ser transparente para el cliente (su programa vb.net).