Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Elastyczny klucz obcy

Jednym ze sposobów rozwiązania tego problemu byłoby dodanie tabeli do bazy danych, która będzie działać jak podstawa dla innych tabel i połączenie jej relacją jeden do jednego z innymi tabelami, a następnie połączenie tabeli zdarzeń z tą tabelą podstawową.
Pozwoli to zachować integralność danych dla każdej z tabel.
Tabela podstawowa może być tak prosta, jak tylko jedna kolumna, lub może zawierać kolumny, które mają wspólne dla wszystkich innych tabel, implementując w ten sposób coś w rodzaju „ dziedziczenia” w Twojej strukturze danych.

Utwórz tabelę podstawową (zakładając, że nie ma wspólnych kolumn między innymi tabelami):

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

Następnie dla każdej innej tabeli, do której musi się odwoływać ObjectId w Events tabela:

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

Pozostaje tylko wstawić nową wartość do TblObjectBase dla dowolnego wstawienia w innych tabelach. Można to łatwo osiągnąć za pomocą procedur składowanych lub zamiast wyzwalaczy wstawiania.
Procedura wstawiania może wyglądać tak:

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

Zamiast wyzwalacza wstawiania wyglądałoby tak:

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

Jeśli zdecydujesz się na użycie zamiast wstawiania, fakt, że wartość tożsamości pochodzi z innej tabeli, powinien być niewidoczny dla klienta (twojego programu vb.net).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja AWS Lambda do połączenia z SQL Server za pomocą Pythona

  2. Audyt zmian danych SQL Server

  3. Filtruj raport Power BI na podstawie bieżącego użytkownika

  4. dynamiczna oś sql na serwerze sql

  5. Konwersja nie powiodła się podczas konwertowania wartości varchar „none” na typ danych int