久久精品视频亚洲|国产免费成人在线视频|欧美三级在线高清不卡|国产区第一页亚洲成人综合|2022精品天堂在线视频|久久SE精品一区精品二区|久久久精品久久波多野结衣av|亚洲欧美日韩国产成人精品在线

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

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

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

在SQL Server中使用檢查約束來驗證數(shù)據(jù)

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

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

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

  創(chuàng)建檢查約束的一個方法是在表創(chuàng)建時進行。這是一個簡單的CREATE TABLE腳本,它創(chuàng)建了一個單獨的檢查約束:

   CREATE TABLE dbo.Payroll
  (

  ID int PRIMARY KEY,

  PositionID INT,

  SalaryType nvarchar(10),

  Salary decimal(9,2)

  CHECK (Salary < 150000.00)

  );

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

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。
  上面的每個例子都創(chuàng)建了一個單獨的條件字段檢查約束。一個檢查約束表達式可以有多個條件。下面是一個例子,它顯示了一個有多個條件的檢查約束:

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 拒絕一條記錄,這個檢查約束的邏輯表達式的最終結(jié)果需要是FALSE。因此,在這個例子中,這個檢查約束驗證了一個Salary大于$10.00并小于$150,000.00。當這個檢查約束中的這些條件中的任何一個為FALSE,那么在Payroll表中將不會插入或更新一條記錄,并會顯示一個錯誤信息。

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

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)建了一個單獨的表約束,它檢查Salary字段,但是它不是關(guān)聯(lián)到字段,而是關(guān)聯(lián)到這個表。在這個檢查約束中我可以使用我的表中的任何字段,只要我想,因為它是一個表檢查約束,但是在我的例子中,我只使用了Salary字段。注意,這個CHECK子句將使得SQL Server生成一個檢查約束名稱,因為我沒有給這個約束名稱。

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

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

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

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

  你可以使用一個單獨的ALTER TABLE語句來一次添加多個檢查約束到你的表中。下面是這么做的例子:

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)使用一個單獨的ADD CONSTRAINT子句添加了SalaryType和Salary約束。

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

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

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

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

  前一個例子的另一個方法是在不只一個的字段中使用這個值,從而確定某一指定字段值是否是有效的。例如,假設(shè)我想確保當我輸入一個“Hourly” SalaryType時,我希望Salary小于$100.00,或輸入“Monthly” SalaryType時,Salary不超過$10,000,而當輸入一個“Annual” SalaryType時任何Salary數(shù)值都可以。要實現(xiàn)這個約束,我使用下面的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''''));

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

  了解當值為Null時會發(fā)生什么

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

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

ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

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

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

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

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

ALTER TABLE dbo.Payroll
  WITH NOCHECK ADD CONSTRAINT CK_Payroll_SalaryType

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

  and SalaryType is not NULL);

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

  通過檢查約束進行數(shù)據(jù)驗證

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

在線客服

customer service