Sql-Server

使用第二個表作為唯一鍵?

  • August 23, 2019

這是一個相當菜鳥的問題。我使用一個老式的 PowerBuilder 軟體 (PowerCampus),它有一些 80 年代和 90 年代的奇怪設計決定。

可能是系統中最重要的表,dbo.ACADEMIC只有一個由多列組成的聚集主鍵。我需要能夠通過不可變的鍵(例如 GUID)SELECTUPDATE行,但我也無法更改表。dbo.ACADEMIC

我不能修改這個表的結構的原因有很多,其中最主要的是一所學校嘗試過它並破壞了桌面客戶端軟體。

ACADEMIC這是’s 主鍵的簡化範例:

PEOPLE_CODE_ID ACADEMIC_YEAR ACADEMIC_TERM CURRICULUM
-------------- ------------- ------------- ----------
P000011111     1996          SPRING        URBAN
P000022222     2012          SPRING        HCSMGT
P000033333     2002          SUMMER        CHEMIS
P000044444     2015          FALL          SEDUCA
P000055555     1983          SUMMER        POLSCI

作為鍵的一部分的某些列會發生很大變化——例如,當學生更改課程時。由於缺少不可變的 id,因此與其他系統集成非常困難。

這可以通過創建另一個具有唯一主鍵和標識列的表來解決ACADEMIC嗎?然後可以建構一個視圖,顯示來自ACADEMICid列的所有數據;集成項目可以使用此視圖。

建議custom.AcademicKey表:

id                                   PEOPLE_CODE_ID ACADEMIC_YEAR ACADEMIC_TERM CURRICULUM
------------------------------------ -------------- ------------- ------------- ----------
956EB195-C7C3-4E47-9A1B-0000191B95A2 P000011111     1996          SPRING        URBAN
FE00D2F4-5F5E-45D2-AB63-00002CC92F40 P000022222     2012          SPRING        HCSMGT
C1AF44CD-DDD1-4D46-A19E-0000A841B70F P000033333     2002          SUMMER        CHEMIS
D4E8FC3F-CECC-4195-9924-0000B9BC33A7 P000044444     2015          FALL          SEDUCA
456B16ED-C504-456B-A2E5-00019F244A95 P000055555     1983          SUMMER        POLSCI

與集群鍵綁定的外鍵會ACADEMIC完成此操作嗎?

是否必須添加觸發器ACADEMIC才能將新行填充到 中AcademicKey

這可以通過創建另一個具有唯一主鍵以及來自 ACADEMIC 的標識列的表來解決嗎?

是的。最低限度您需要一個外鍵和一個 AFTER INSERT 觸發器。

例如

use tempdb
go
--create schema custom
go

--drop table if exists custom.AcademicKey
--drop table if exists dbo.Academic
go
create table dbo.Academic
(
  PEOPLE_CODE_ID varchar(20), 
  ACADEMIC_YEAR int, 
  ACADEMIC_TERM varchar(10),
  CURRICULUM varchar(20),
  constraint pk_Academic
    primary key (PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM)
)
create table custom.AcademicKey
(
  Id uniqueidentifier default (newsequentialid()),
  PEOPLE_CODE_ID varchar(20), 
  ACADEMIC_YEAR int, 
  ACADEMIC_TERM varchar(10),
  CURRICULUM varchar(20),
  constraint pk_Academic
    primary key nonclustered (id),
  constraint ak_AcademicKey
    unique clustered (PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM),
  constraint fk_AcademicKey_Adademic
    foreign key (PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM)
    references Academic (PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM)
    on update cascade
    on delete cascade
)

go

create or alter trigger Academic_CreateAcademicKey 
 on dbo.Academic after insert
as
begin
   set nocount on;

   insert into custom.AcademicKey(PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM)
   select PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM
   from inserted;
end

go 

insert into Academic(PEOPLE_CODE_ID, ACADEMIC_YEAR, ACADEMIC_TERM, CURRICULUM)
values ('P000011111',     1996,          'SPRING',      ' URBAN')

select * from custom.AcademicKey

update Academic set CURRICULUM = 'CHEMIS' where PEOPLE_CODE_ID = 'P000011111'

select * from custom.AcademicKey

delete from Academic where PEOPLE_CODE_ID = 'P000011111'

select * from custom.AcademicKey

引用自:https://dba.stackexchange.com/questions/246035