1. 程式人生 > >《SQL Server 2008從入門到精通》--20180629

《SQL Server 2008從入門到精通》--20180629

fault 創建表 問題 入門到 多個 依然 系統 name 聯合主鍵

約束

主關鍵字約束(Primary Key Constraint)

用來指定表中的一列或幾列組合的值在表中具有唯一性。建立主鍵的目的是讓外鍵來引用。

Primary Key的創建方式

在創建表時創建Primary Key

CREATE TABLE table1(
    t_id VARCHAR(12) ,
    t_name VARCHAR(20),
    t_phone VARCHAR(20),
    CONSTRAINT t_idss PRIMARY KEY(t_id)
);

對t_id列創建主鍵,約束名為t_idss。

刪除Primary Key
ALTER TABLE table1
DROP CONSTRAINT t_idss;

約束名與列名不一致,此處填寫約束名

向已有表中添加Primary Key
ALTER TABLE table1
ADD CONSTRAINT t_idss
PRIMARY KEY(t_id);
添加Primary Key的另一種示例
ALTER TABLE Products
ADD PRIMARY KEY(prod_id);

雖然上述代碼運行沒問題,查看表格設計也可以看到Primary Key設置成功,但是在刪除Primary Key操作時會提示:
消息3728,級別16,狀態1,第1 行
‘prod_id‘ 不是約束。
消息3727,級別16,狀態0,第1 行
未能刪除約束。請參閱前面的錯誤信息。


原因是添加Primary Key語句中沒有用CONSTRAINT指明約束名,系統自動生成了主鍵名和約束名,要先查看主鍵名和約束名,刪除時填寫的也是約束名。
這種情況的正確刪除方法

ALTER TABLE Products
DROP CONSTRAINT CK__Products__prod_p__1A14E395;
ALTER TABLE Products
DROP CONSTRAINT PK__Products__56958AB222AA2996;
多列組合添加主鍵約束
CREATE TABLE table1(
    t_id VARCHAR(12),
    s_id VARCHAR(20),
    score FLOAT,
    CONSTRAINT ts_id PRIMARY KEY(t_id,s_id)
);
外關鍵字約束(Foreign Key Constraint)

定義了表之間的關系,用來維護兩個表之間的一致性的關系。
在創建表時創建Foreign Key Constraint

CREATE TABLE table2(
    s_id VARCHAR(20),
    s_name VARCHAR(12),
    s_tellphone VARCHAR(11),
    s_address VARCHAR(20),
    CONSTRAINT PK_s_id PRIMARY KEY(s_id),
);--首先新建table2,設置s_id為主鍵

CREATE TABLE table1(
    t_id VARCHAR(12),
    s_id VARCHAR(20),
    score FLOAT,
    CONSTRAINT pk_ts_id PRIMARY KEY(t_id,s_id),--新建table1,對t_id和s_id設置聯合主鍵,鍵名pk_ts_id
    CONSTRAINT fk_s_id FOREIGN KEY(s_id)--對s_id設置外鍵fk_s_id
    REFERENCES table2(s_id)--外鍵fk_s_id外鍵關聯table2的列s_id
    ON DELETE CASCADE--設置在table1的s_id刪除時table2的s_id同時刪除
    ON UPDATE CASCADE--設置在table1的s_id更新時table2的s_id同時更新
);

註:對table1設置外鍵關聯table2,在插入數據時需要先插入table2的數據,才能成功插入table1的數據。更改table2.s_id數據,table1.s_id數據也會自動改變。但是更改table1.s_id數據,執行時報外鍵沖突會報。總之對table1設置外鍵關聯table2後,table1的數據跟著table2走,不能反著來。

添加和刪除外鍵約束同主鍵。

UNIQUE約束

除主鍵外另一種可以定義唯一約束的類型,允許空值。添加UNIQUE的方法同上,這裏只簡單舉例。

USE test
GO
ALTER TABLE table2
ADD CONSTRAINT uk_s_tellphone
UNIQUE(s_tellphone);
CHECK約束

分為表約束和列約束,用於限制字段值在某個範圍。

添加CHECK約束
ALTER TABLE table2
ADD sex CHAR(2);--在table表中添加sex,數據類型為CHAR,用來存放性別
GO
ALTER TABLE table2
ADD CONSTRAINT ck_sex CHECK(sex in(‘男‘,‘女‘));

註:此時sex列數據類型不能是bit,如果填寫bit,只能存儲0和1,用CHECK約束限制結果為男和女就會報錯。

在創建表的時候添加CHECK 約束
CREATE TABLE table3(
    t3_id VARCHAR(12),
    t3_name VARCHAR(20),
    t3_class VARCHAR(12),
    t3_type VARCHAR(12),
    CONSTRAINT ck_t3_type CHECK(t3_type in(‘類型1‘,‘類型2‘,‘類型3‘)) 
)

添加了約束後如果插入不符合約束的數據

INSERT INTO table3(
    t3_id,
    t3_name,
    t3_class,
    t3_type
)VALUES(
‘2018038219‘,
‘李建‘,
‘社會與科學‘,
‘任何數據‘
);

消息547,級別16,狀態0,第1 行
INSERT 語句與CHECK 約束"ck_t3_type"沖突。該沖突發生於數據庫"test",表"dbo.table3", column ‘t3_type‘。
語句已終止。

刪除CHECK約束
ALTER TABLE table3
DROP CONSTRAINT ck_t3_type;
DEFAULT約束

通過定義列的默認值或使用數據庫的默認值對象綁定表列,來指定列的默認值。

在建表時添加DEFAULT約束
CREATE TABLE table3(
    t3_id VARCHAR(12),
    t3_name VARCHAR(20),
    t3_class VARCHAR(12),
    t3_type VARCHAR(12) DEFAULT ‘類型1‘ 
)
刪除DEFAULT約束
ALTER TABLE table3
DROP CONSTRAINT DF__table3__t3_type__3D5E1FD2;
--DF__table3__t3_type__3D5E1FD2是DEFAULT約束的約束名
添加約束不指定約束名
ALTER TABLE table3
ADD DEFAULT ‘類型2‘ FOR t3_type;
GO
添加約束指定約束名
ALTER TABLE table3
ADD CONSTRAINT df_t3_type
DEFAULT ‘類型2‘ FOR t3_type;
GO
NOT NULL約束

約束字段值不為空。

建表時設置NOT NULL約束
CREATE TABLE table3(
    t3_id VARCHAR(12) NOT NULL,
    t3_name VARCHAR(20) NOT NULL,
    t3_class VARCHAR(12) NOT NULL,
    t3_type VARCHAR(12) NOT NULL 
)
為已存在的列添加NOT NULL約束
ALTER TABLE table3
ALTER COLUMN t3_type VARCHAR(12) NOT NULL;
刪除NOT NULL約束
ALTER TABLE table3
ALTER COLUMN t3_type VARCHAR(12) NULL;
GO

自定義默認值對象維護數據完整性

CREATE DEFAULT date_today AS GETDATE();
--新建默認值對象名date_today,默認值為getdate()函數,獲取當前日期
GO
EXEC sp_addtype date_time,‘date‘,‘NULL‘;
--利用存儲過程新建自定義數據類型date_time,參照系統數據類型date
GO
EXEC sp_bindefault ‘date_today‘,‘date_time‘;
--將默認值對象date_today綁定到自定義數據類型date_time上
GO
CREATE TABLE table3(--新建table3,設置字段t3_date的數據類型為date_time
    t3_id VARCHAR(12),
    t3_name VARCHAR(20),
    t3_class VARCHAR(12),
    t3_type VARCHAR(12),
    t3_date date_time
);
GO
INSERT INTO table3(--為新建表table3插入一條數據,不指定t3_date的值,看默認值是否有效
    t3_id,
    t3_name,
    t3_class,
    t3_type
)VALUES(
‘2018038220‘,
‘李建‘,
‘社會與科學‘,
‘類型1‘
);
GO
SELECT * FROM table3;--查詢table3數據,看t3_date是否有默認值為當前日期

查詢結果如下
技術分享圖片

直接將默認值對象綁定給列
ALTER TABLE table3
ADD t3_date1 DATE;--在table3表中新增一列t3_date1,數據類型為DATE
GO
EXEC sp_bindefault ‘date_today‘,‘table3.t3_date1‘;
--直接將默認值對象date_today綁定到table3的t3_date1列
GO
INSERT INTO table3(--為新建表table3插入一條數據,不指定t3_date和t3_date1的值,看默認值是否有效
    t3_id,
    t3_name,
    t3_class,
    t3_type
)VALUES(
‘2018038221‘,
‘李建‘,
‘社會與科學‘,
‘類型‘
);
GO
SELECT * FROM table3;
GO

查詢結果如下
技術分享圖片

存儲過程查詢默認值對象的所有者
USE test
EXEC sp_help date_today;
GO

結果如圖所示
技術分享圖片

刪除默認值對象
DROP DEFAULT date_today;

刪除不成功,提示以下信息:
消息3716,級別16,狀態3,第1 行
無法刪除默認值‘date_today‘,因為它已綁定到一個或多個列。
那麽我們知道,當一個默認值對象綁定了列之後,就無法刪除它,如果想要刪除,就必須先解綁。在上面的操作中,我們的默認值對象date_today綁定了test數據庫table3表的t3_date1字段。

對列解綁默認值對象
USE test
GO
EXEC sp_unbindefault ‘table3.t3_date1‘;

此時我們再次嘗試刪除默認值對象,發現還是不行,此時要註意,在上面的操作中,默認值對象date_today不止綁定了t3_date1列,還綁定了自定義數據類型date_time,並將該數據類型定義給了t3_date列,我們還需要對date_time解綁默認值對象。

EXEC sp_unbindefault ‘date_time‘;

此時再次刪除默認值對象,就可以成功刪除。刪除默認值對象後,原先綁定的字段不會再有默認值。

自定義規則維護數據完整性

規則是對列或自定義數據類型的值的規定和限制。自定義規則的表達式一定要返回布爾類型的值,並且表達式中不能包含多個變量。

CREATE RULE score_rule AS @math_score>=0;
GO--新建規則score_rule,參數@math_score
EXEC sp_addtype ‘score_type‘,‘float‘,‘NULL‘;
GO--新建自定義數據類型score_type
CREATE TABLE table_score(--新建表table_score,預設mt_score和at_score字段用於綁定規則
s_id VARCHAR(4),
s_name VARCHAR(10),
mt_score float,--該字段將用於規則score_rule綁定到列
at_score score_type--該字段將用於規則score_rule綁定到自定義數據類型
);
GO
EXEC sp_bindrule ‘score_rule‘,‘score_type‘;
GO--將score_rule規則綁定到自定義數據類型score_type
EXEC sp_bindrule ‘score_rule‘,‘table_score.mt_score‘;
GO--將score_rule規則綁定到table_score表的mt_score列

----以下進行規則測試
INSERT INTO table_score(
s_id,
s_name,
mt_score,
at_score
)VALUES(
‘0001‘,
‘張華‘,
‘-1‘,
‘-1‘
);
GO

進行違反規則的插入後,數據庫報錯
消息513,級別16,狀態0,第1 行
列的插入或更新與先前的CREATE RULE 語句所指定的規則發生沖突。該語句已終止。沖突發生於數據庫‘test‘,表‘dbo.table_score‘,列‘mt_score‘。
語句已終止。
很明顯,mt_score的插入值為-1,違反了必須大於等於0的規則,數據庫報錯。將mt_score的插入值改成符合規則的數據,再次運行插入語句,數據庫依然會報錯,因為at_score字段的插入值也是違反規則的。將兩個數據改成符合規則的返回,執行成功。

註:新建規則時表達式一定要是返回布爾類型的值,否則會報錯

消息4145,級別15,狀態1,過程sum_score,第1 行
在應使用條件的上下文(在‘;‘ 附近)中指定了非布爾類型的表達式。

刪除自定義規則

和自定義默認值對象一樣,刪除自定義規則要求該規則先與字段和自定義數據類型解綁。在上面的操作中,score_rule規則與自定義數據類型score_type以及列mt_score已綁定。因此執行以下語句:

EXEC sp_unbindrule ‘score_type‘;
GO--解除規則score_rule與score_type之間的綁定
EXEC sp_unbindrule ‘table_score.mt_score‘;
GO--解除規則score_rule與表table_score的mt_score列的綁定
DROP RULE score_rule;--刪除score_rule規則

註:經過試驗,一個列只能綁定1條規則,如果對一個列綁定2條規則,前一條規則會被後一條規則頂替。

查看自定義規則
EXEC sp_help ‘score_rule‘;

結果如圖所示
技術分享圖片

查看自定義規則的定義信息
EXEC sp_helptext ‘score_rule‘;
GO

結果如圖所示
技術分享圖片

《SQL Server 2008從入門到精通》--20180629