一道本国产不卡视频|无码av午夜福利人妻|中文字幕亚洲网址第1页|亚洲人成网站在线播放观看|国产精品喷浆丁香美女社区|亚洲人妻日本香蕉鸡巴视频|欧美一区日韩一区中文字幕页|亚洲国产精品美女久久久久8k

IE9下訪問(wèn)可能不佳,推薦使用以下版本瀏覽器X

歡迎您來(lái)到炎黃網(wǎng)絡(luò)!

服務(wù)熱線:400-0000-786

在SQL Server中使用檢查約束來(lái)驗(yàn)證數(shù)據(jù)

—— 閱讀:12464次
  什么是檢查約束?
  檢查約束是一個(gè)規(guī)則,它確認(rèn)一個(gè)SQL Server表中某條記錄中的數(shù)據(jù)可接受的字段值。檢查約束幫助執(zhí)行域完整性。域完整性定義了一個(gè)數(shù)據(jù)庫(kù)表中字段的有效值。檢查約束可以驗(yàn)證一個(gè)單獨(dú)字段或一些字段的域完整性。你對(duì)一個(gè)單獨(dú)的字段可以有多個(gè)檢查完整性。如果被插入或更新的數(shù)據(jù)違反了一個(gè)檢查約束,那么數(shù)據(jù)庫(kù)引擎將不允許這個(gè)插入或更新的操作發(fā)生。

  檢查約束包括一個(gè)邏輯表達(dá)式,用以確認(rèn)什么是有效的表達(dá)式。邏輯表達(dá)式可能是一個(gè)單獨(dú)的表達(dá)式比如“Salary < 200000.00”,或多個(gè)表達(dá)式,比如“RentalDate > GETDATE() and RentalDate < DATEADD(YY,1,GETDATE())”。如果一個(gè)邏輯表達(dá)式的一個(gè)檢查約束返回了FALSE值,那么這個(gè)檢查約束將限制這個(gè)表中數(shù)據(jù)插入或更新。對(duì)于邏輯表達(dá)式返回的是FALSE以外的值的所有記錄將通過(guò)這個(gè)檢查約束并允許記錄被更新或插入。為了這個(gè)記錄能夠被插入或更新,與給定INSERT或UPDATE語(yǔ)句相關(guān)的所有數(shù)據(jù)都不能進(jìn)行檢查約束失敗(返回一個(gè)FALSE值)。檢查約束可以在字段級(jí)別或表級(jí)別被創(chuàng)建。

  在一個(gè)CREATE TABLE語(yǔ)句上創(chuàng)建檢查約束

  創(chuàng)建檢查約束的一個(gè)方法是在表創(chuàng)建時(shí)進(jìn)行。這是一個(gè)簡(jiǎn)單的CREATE TABLE腳本,它創(chuàng)建了一個(gè)單獨(dú)的檢查約束:

   CREATE TABLE dbo.Payroll
  (

  ID int PRIMARY KEY,

  PositionID INT,

  SalaryType nvarchar(10),

  Salary decimal(9,2)

  CHECK (Salary < 150000.00)

  );

  
  這里我有一個(gè)CHECK 子句,它與Salary字段關(guān)聯(lián)。這是一個(gè)字段級(jí)別的約束。如果你創(chuàng)建一個(gè)字段級(jí)別的約束,那么你在你的檢查約束的邏輯表達(dá)式中只能使用這個(gè)字段名稱。這個(gè)檢查約束只允許Salary字段低于$150,000.00。當(dāng)我的表創(chuàng)建之后,這個(gè)CHECK約束也將被創(chuàng)建,并被賦予一個(gè)系統(tǒng)生成的約束名稱。如果你想在一個(gè)CREATE TABLE操作期間命名你的檢查約束,那么你可以運(yùn)行下面的代碼:

CREATE TABLE dbo.Payroll
  (

  ID int PRIMARY KEY,

  PositionID INT,

  SalaryType nvarchar(10),

  Salary decimal(9,2)

  CONSTRAINT CK_Payroll_Salary CHECK (Salary < 150000.00)

  );



  這里命名了我的檢查約束CK_Payroll_Salary。
  上面的每個(gè)例子都創(chuàng)建了一個(gè)單獨(dú)的條件字段檢查約束。一個(gè)檢查約束表達(dá)式可以有多個(gè)條件。下面是一個(gè)例子,它顯示了一個(gè)有多個(gè)條件的檢查約束:

CREATE TABLE dbo.Payroll
  (

  ID int PRIMARY KEY,

  PositionID INT,

  SalaryType nvarchar(10),

  Salary decimal(9,2)

  CONSTRAINT CK_Payroll_Salary

  CHECK (Salary > 10.00 and Salary < 150000.00)

  );

  
  記住,為了讓SQL Server 拒絕一條記錄,這個(gè)檢查約束的邏輯表達(dá)式的最終結(jié)果需要是FALSE。因此,在這個(gè)例子中,這個(gè)檢查約束驗(yàn)證了一個(gè)Salary大于$10.00并小于$150,000.00。當(dāng)這個(gè)檢查約束中的這些條件中的任何一個(gè)為FALSE,那么在Payroll表中將不會(huì)插入或更新一條記錄,并會(huì)顯示一個(gè)錯(cuò)誤信息。

  如果你想創(chuàng)建一個(gè)表級(jí)別的檢查約束,那么你可以運(yùn)行下面的代碼:

CREATE TABLE dbo.Payroll
  (

  ID int PRIMARY KEY,

  PositionID INT,

  Salary decimal(9,2),

  SalaryType nvarchar(10),

  CHECK (Salary > 10.00 and Salary < 150000.00)

  );

  
  這里我創(chuàng)建了一個(gè)單獨(dú)的表約束,它檢查Salary字段,但是它不是關(guān)聯(lián)到字段,而是關(guān)聯(lián)到這個(gè)表。在這個(gè)檢查約束中我可以使用我的表中的任何字段,只要我想,因?yàn)樗且粋(gè)表檢查約束,但是在我的例子中,我只使用了Salary字段。注意,這個(gè)CHECK子句將使得SQL Server生成一個(gè)檢查約束名稱,因?yàn)槲覜](méi)有給這個(gè)約束名稱。

  在一個(gè)現(xiàn)有的表上創(chuàng)建一個(gè)檢查約束

  有時(shí),在你設(shè)計(jì)和創(chuàng)建了一個(gè)表后,你想對(duì)一個(gè)表添加一個(gè)檢查約束。這可以通過(guò)使用ALTER TABLE 語(yǔ)句來(lái)完成。下面是這么做的例子:
  ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

  CHECK (SalaryType in (''''Hourly'''',''''Monthly'''',''''Annual''''));

  
  在這里我創(chuàng)建了一個(gè)檢查約束,它將檢查我的Payroll表中的所有記錄在SalaryType字段中只有“Hourly”、“ Monthly”或“Annual”值。我還用一個(gè)名稱命名了我的檢查約束,在這個(gè)例子中是“CK_Payroll_SalaryType”。

  你可以使用一個(gè)單獨(dú)的ALTER TABLE語(yǔ)句來(lái)一次添加多個(gè)檢查約束到你的表中。下面是這么做的例子:

ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

  CHECK (SalaryType in (''''Hourly'''',''''Monthly'''',''''Annual'''')),

  CONSTRAINT CK_Payroll_Salary

  CHECK (Salary > 10.00 and Salary < 150000.00);

  
  在這里我已經(jīng)使用一個(gè)單獨(dú)的ADD CONSTRAINT子句添加了SalaryType和Salary約束。

  創(chuàng)建多個(gè)字段約束

  你沒(méi)有必要?jiǎng)?chuàng)建只能檢查一個(gè)單獨(dú)字段的值的約束。你可以創(chuàng)建一次檢查多個(gè)字段中的值的約束。例如,如果我想創(chuàng)建一個(gè)檢查上面所創(chuàng)建的Salary和SalaryType約束的單獨(dú)約束,那么可以使用下面的代碼:

ALTER TABLE dbo.Payroll WITH NOCHECK
  ADD CONSTRAINT CK_Payroll_Salary_N_SalaryType

  CHECK (SalaryType in (''''Hourly'''',''''Monthly'''',''''Annual'''')

  and Salary > 10.00 and Salary < 150000.00);

  
  這個(gè)單獨(dú)約束所做的事情和上面兩個(gè)約束一樣。記住,當(dāng)你這么做時(shí),要了解是SalaryType 、Salary 還是兩個(gè)字段都違反了你的檢查約束就更很困難了。.

  前一個(gè)例子的另一個(gè)方法是在不只一個(gè)的字段中使用這個(gè)值,從而確定某一指定字段值是否是有效的。例如,假設(shè)我想確保當(dāng)我輸入一個(gè)“Hourly” SalaryType時(shí),我希望Salary小于$100.00,或輸入“Monthly” SalaryType時(shí),Salary不超過(guò)$10,000,而當(dāng)輸入一個(gè)“Annual” SalaryType時(shí)任何Salary數(shù)值都可以。要實(shí)現(xiàn)這個(gè)約束,我使用下面的ADD CONSTRAINT子句:
ALTER TABLE dbo.Payroll WITH NOCHECK
  ADD CONSTRAINT CK_Payroll_SalaryType_Based_On_Salary

  CHECK ((SalaryType = ''''Hourly'''' and Salary < 100.00) or

  (SalaryType = ''''Monthly'''' and Salary < 10000.00) or

  (SalaryType = ''''Annual''''));

  
  這里,我將多個(gè)字段條件一起使用并使用一個(gè)“or”條件來(lái)分隔它們,所以我的檢查約束可以驗(yàn)證每個(gè)不同的SalaryType的Salary數(shù)量。

  了解當(dāng)值為Null時(shí)會(huì)發(fā)生什么

  回憶下在本篇文章的“什么是檢查約束”章節(jié)中所說(shuō)的關(guān)于記錄是怎樣只在檢查約束得出結(jié)果FALSE時(shí)才認(rèn)為檢查約束沒(méi)有通過(guò)。因此,字段中的NULL值可能允許你輸入數(shù)據(jù)到你的數(shù)據(jù)庫(kù)中,而這并不滿足你的需求。

  假設(shè)我在我的payroll表上只有CK_Paryroll_SalaryType 檢查約束。這里需要回憶的就是這個(gè)檢查約束:

ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

  CHECK (SalaryType in (''''Hourly'''',''''Monthly'''',''''Annual''''));

  
  現(xiàn)在你運(yùn)行下面的INSERT語(yǔ)句:

  INSERT INTO dbo.Payroll values (1, 1, ''''Hourly'''',25.00);

  INSERT INTO dbo.Payroll values (2, 2, NULL, 25.00);

  INSERT INTO dbo.Payroll values (3, 3, ''''Horly'''',25.00);

  會(huì)發(fā)生什么?會(huì)只有第一個(gè)INSERT語(yǔ)句起作用嗎?第二個(gè)和第三個(gè)INSERT語(yǔ)句會(huì)怎樣?它們都違反CK_Payroll_SalaryType嗎?結(jié)果是只有第三個(gè)INSERT語(yǔ)句失敗了。它失敗是由于SalaryType輸入錯(cuò)誤,它不是“Hourly”、“ Monthly”或“Annual”。為什么第二個(gè)INSERT沒(méi)有得出false呢?顯然,“NULL”不是SalaryTypes的有效值。第二個(gè)INSERT語(yǔ)句起作用的原因是在第二個(gè)INSERT語(yǔ)句運(yùn)行時(shí),CK_Payroll_SalaryType約束不是FALSE。因此,數(shù)據(jù)庫(kù)引擎插入了這條記錄。那么為什么會(huì)出現(xiàn)這種情況呢?這是因?yàn)镹ULL值用在比較操作中時(shí),它被當(dāng)作UNKNOWN。因?yàn)閁NKNOWN不是FALSE,所以沒(méi)有違反檢查約束。因此,當(dāng)你編寫(xiě)你的檢查約束時(shí),你需要對(duì)需要拒絕包含NULL值的地方很謹(jǐn)慎。另一個(gè)編寫(xiě)上面的約束從而使得拒絕SalaryType值為NULL的方法是如下編寫(xiě)你的約束:

ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

  CHECK ((SalaryType in (''''Hourly'''',''''Monthly'''',''''Annual''''))

  and SalaryType is not NULL);

  
  另一個(gè)選擇是使SalaryType成為一個(gè)非NULL字段。如果你這么做就不會(huì)違反檢查約束,但是反過(guò)來(lái)你會(huì)得到一個(gè)錯(cuò)誤信息顯示你不能插入一個(gè)NULL值到你的表中。

  通過(guò)檢查約束進(jìn)行數(shù)據(jù)驗(yàn)證

  通過(guò)使用檢查約束,你可以確保你的數(shù)據(jù)庫(kù)只包含通過(guò)了約束的數(shù)據(jù)。這使得你可以讓數(shù)據(jù)庫(kù)引擎控制你的數(shù)據(jù)驗(yàn)證。這么做將使得你的應(yīng)用程序不需要在每個(gè)你希望插入一條記錄或更新一條記錄到一個(gè)表中的地方都寫(xiě)數(shù)據(jù)驗(yàn)證規(guī)則的代碼。檢查約束是執(zhí)行數(shù)據(jù)驗(yàn)證的一個(gè)簡(jiǎn)潔方法。
收縮

在線客服

customer service