天天看點

外鍵ON DELETE 兩種方法的測試

/**
測試目的,對外鍵的 ON DELETE 的兩種方法的測試,了解是如何工作的。
這兩種方法是:
ON DELETE CASCADE SET NULL
ON DELETE CASCADE
首先建立兩張表,T1和T11
T1表是主表,T11表是明細表。
T1表的主鍵是T11表的外鍵。
下面以SQL Server 2012 為例測試
**/
IF EXISTS (SELECT NAME From sysobjects Where type='U' and NAME='App_Officer')
  DROP TABLE T1;
GO
-- T1表主鍵為FKEY,主鍵限制的名稱為:PK_T1_FKEY
CREATE TABLE T1
(
  FKEY  INT,
  FNAME VARCHAR(20),
  CONSTRAINT PK_T1_FKEY PRIMARY KEY (FKEY)
);
-- 檢視主鍵情況
SELECT M.name Table_name,I.name Primary_key_name,C.name ColName,C.column_id,IC.key_ordinal Primary_key_id
FROM
SYS.objects M
JOIN
SYS.columns C
ON M.object_id = C.object_id
JOIN
SYS.indexes I
ON M.object_id = I.object_id
JOIN
SYS.index_columns IC
ON M.object_id = IC.object_id AND I.index_id = IC.index_id AND C.column_id = IC.column_id
WHERE M.name = 'T1'

/** 檢視主鍵結果如下
---------------------------------------------------------------------
Table_name  Primary_key_name    ColName column_id   Primary_key_id
T1          PK_T1_FKEY          FKEY    1           1
---------------------------------------------------------------------
**/
INSERT INTO T1 VALUES (1,'PAUL');
SELECT * FROM T1;
/** 查詢結果如下
---------------------------------------------------------------------
FKEY    FNAME
1       PAUL
---------------------------------------------------------------------
**/

IF EXISTS (SELECT NAME From sysobjects Where type='U' and NAME='App_Officer')
  DROP TABLE T11;
GO
CREATE TABLE T11
(
  SKEY INT,
  PID  INT,
  CONSTRAINT PK_T11_SKEY PRIMARY KEY (SKEY),
  CONSTRAINT FK_T11_PID  FOREIGN KEY (PID) REFERENCES T1(FKEY) ON DELETE SET NULL
);
-- 檢視主鍵情況
SELECT M.name Table_name,I.name Primary_key_name,C.name ColName,C.Column_id,IC.key_ordinal Primary_key_id
FROM
SYS.objects M
JOIN
SYS.columns C
ON M.object_id = C.object_id
JOIN
SYS.indexes I
ON M.object_id = I.object_id
JOIN
SYS.index_columns IC
ON M.object_id = IC.object_id AND I.index_id = IC.index_id AND C.column_id = IC.column_id
WHERE M.name = 'T11'

/** 檢視主鍵結果如下
---------------------------------------------------------------------
Table_name  Primary_key_name    ColName Column_id   Primary_key_id
T1          PK_T11_SKEY         SKEY    1           1
---------------------------------------------------------------------
**/

-- 檢視外鍵情況
SELECT M.name Table_name,F.name Foreign_key_name,C.name ColName,C.Column_id,FC.referenced_column_id Referenced_Column_id
FROM
SYS.objects M
JOIN
SYS.columns C
ON M.object_id = C.object_id
JOIN
SYS.foreign_keys F
ON M.object_id = F.parent_object_id
JOIN
SYS.foreign_key_columns FC
ON M.object_id = FC.parent_object_id AND F.object_id = FC.constraint_object_id AND C.column_id = FC.parent_column_id
WHERE M.name = 'T11'

/** 檢視外鍵結果如下
------------------------------------------------------------------------
Table_name  Primary_key_name    ColName Column_id   Referenced_Column_id
T11         FK_T11_PID          PID     2           1
------------------------------------------------------------------------
**/

INSERT INTO T11 VALUES (1,1);
SELECT * FROM T11 WHERE SKEY = 1;
/** 查詢結果如下
---------------------------------------------------------------------
SKEY    PID
1       1
---------------------------------------------------------------------
**/
DELETE FROM T1 WHERE FKEY = 1;
SELECT * FROM T11 WHERE SKEY = 1;
/** 查詢結果如下
---------------------------------------------------------------------
SKEY    PID
1       NULL
---------------------------------------------------------------------
**/
DELETE FROM T11 WHERE SKEY = 1;

ALTER TABLE T11 DROP CONSTRAINT FK_T11_PID;
ALTER TABLE T11 ADD CONSTRAINT FK_T11_PID FOREIGN KEY(PID) REFERENCES T1(FKEY) ON DELETE CASCADE;

INSERT INTO T1 VALUES (1,'PAUL');
INSERT INTO T11 VALUES (1,1);
SELECT * FROM T11;

DELETE FROM T1 WHERE FKEY = 1;
SELECT * FROM T11;
/** 查詢結果如下
---------------------------------------------------------------------
SKEY    PID
---------------------------------------------------------------------
**/

-- 結論
-- ON DELETE CASCADE 級聯删除子表的記錄, 
-- ON DELETE CASCADE SET NULL 将子表記錄的外鍵值設定為 NULL
           

繼續閱讀