Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara Membuat Batasan CHECK di SQL Server (Contoh T-SQL)

Di SQL Server Anda dapat membuat CHECK batasan dalam tabel untuk menentukan nilai data yang dapat diterima dalam satu atau beberapa kolom.

Jika tabel memiliki CHECK kendala di atasnya, dan Anda mencoba memberikan data yang tidak sesuai dengan CHECK kendala, operasi akan gagal dengan kesalahan.

Ini membantu menjaga integritas data, karena membantu mencegah data yang tidak valid masuk ke database.

Saat Anda membuat CHECK kendala, Anda memberikan ekspresi logis yang mengembalikan TRUE atau FALSE . Ekspresi logis inilah yang digunakan untuk memeriksa data.

CHECK kendala mirip dengan kendala kunci asing karena mereka mengontrol nilai-nilai yang dimasukkan ke dalam kolom. Namun, perbedaannya terletak pada cara mereka menentukan nilai mana yang valid:Batasan kunci asing memperoleh daftar nilai yang valid dari tabel lain, sementara CHECK batasan menentukan nilai yang valid dari ekspresi logika.

Batasan dapat didefinisikan pada tingkat kolom atau tingkat tabel. Batasan tingkat kolom hanya berlaku untuk data di kolom itu. Batasan tingkat tabel berlaku untuk seluruh baris, dan memeriksa data dari beberapa kolom.

Di bawah ini adalah contoh pembuatan CHECK tingkat kolom dan tingkat tabel kendala.

Contoh 1 – Membuat Batasan CHECK Level Kolom

Berikut ini contoh pembuatan CHECK tingkat kolom dasar kendala pada saat membuat tabel.

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL,
  CONSTRAINT chkPrice CHECK (Price > 0)
);

Dalam hal ini, CHECK batasan menentukan bahwa semua data dalam Price kolom harus lebih besar dari 0. Dengan kata lain, harga tidak boleh nol dan tidak boleh negatif. Ini adalah batasan tingkat kolom karena berlaku untuk data dalam satu kolom.

Karena ini adalah batasan tingkat kolom, saya dapat mendefinisikannya sebagai bagian dari kolom (tanpa koma). Jadi saya bisa melakukan ini:

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0)
);

Apa pun itu, mari kita coba memasukkan nilai yang tidak valid:

INSERT INTO ConstraintTest ( Price )
VALUES ( 0 );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.

Contoh 2 – Tambahkan Lebih Banyak Kolom dan Batasan Pemeriksaan Tingkat Kolom Lainnya

Mari tambahkan beberapa kolom lagi ke tabel kita lalu tambahkan CHECK tingkat kolom lainnya kendala.

ALTER TABLE ConstraintTest
ADD 
  TeamSize tinyint NOT NULL,
  StartDate date NOT NULL,
  EndDate date NOT NULL,
  CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15)
  ;

Salah satu kolom baru mencatat jumlah anggota tim. Dalam hal ini, aturan bisnisnya adalah sebuah tim harus memiliki setidaknya 3 anggota, tetapi tidak lebih dari 15. Oleh karena itu, database harus mencegah situasi di mana sebuah tim memiliki kurang dari 3 anggota atau lebih dari 15.

Mari kita coba memasukkan nilai yang tidak valid:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 2, '2020-01-01', '1900-02-02' );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Contoh 3 – Tambahkan Batasan CHECK Level Tabel

Sekarang mari tambahkan batasan level tabel. Ini akan memeriksa data dalam dua kolom.

Omong-omong, Anda tidak perlu menambahkan kolom lain untuk menambahkan CHECK paksaan. Anda cukup menambahkan batasan itu sendiri.

Contoh:

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkValidEndDate 
  CHECK (EndDate >= StartDate)
  ;

Dalam hal ini saya menambahkan batasan untuk memastikan bahwa tanggal akhir tidak boleh lebih awal dari tanggal mulai. Ini memeriksa data di dua kolom dan karenanya merupakan batasan tingkat tabel.

Coba masukkan nilai yang tidak valid:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 3, '2020-01-01', '1900-02-02' );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".

Perhatikan bahwa untuk menguji batasan ini, saya harus menambah anggota tim menjadi 3 untuk mencegah batasan sebelumnya dipicu terlebih dahulu (CHECK batasan divalidasi sesuai urutan pembuatannya).

Contoh 4 – Mengubah Batasan CHECK

Anda sebenarnya tidak dapat mengubah CHECK paksaan. Jika Anda perlu mengubahnya, Anda harus menghapusnya dan membuatnya dengan definisi baru.

Contoh:

ALTER TABLE ConstraintTest 
  DROP CONSTRAINT chkTeamSize;

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkTeamSize 
  CHECK (TeamSize >= 5 AND TeamSize <= 20)
  ;

Seperti yang disebutkan, CHECK batasan divalidasi sesuai urutan pembuatannya, jadi ini dapat memengaruhi kesalahan mana yang ditangkap lebih dulu.

Oleh karena itu dalam hal ini, jika saya mencoba memasukkan nilai yang tidak valid (dan juga menyertakan tanggal yang tidak valid), tanggal yang tidak valid akan ditangkap terlebih dahulu:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '1900-02-02' );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".

Jadi untuk memeriksa batasan terbaru saya, saya harus memperbaiki masalah tanggal terlebih dahulu:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '2020-02-02' );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Jadi batasan terbaru saya berfungsi seperti yang diharapkan.

Contoh 5 – PERIKSA Batasan dan Kolom IDENTITAS

Jadi sekarang kita telah menguji batasannya, mari kita lanjutkan dan masukkan data yang valid:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 5, '2020-01-01', '2020-02-02' );

Hasil:

+--------------------+---------+------------+-------------+------------+
| ConstraintTestId   | Price   | TeamSize   | StartDate   | EndDate    |
|--------------------+---------+------------+-------------+------------|
| 13                 | 1.0000  | 5          | 2020-01-01  | 2020-02-02 |
+--------------------+---------+------------+-------------+------------+

Akhirnya kami mendapatkan penyisipan yang berhasil.

Namun, Anda akan melihat bahwa IDENTITY kolom telah bertambah menjadi 13.

Ingat ketika saya pertama kali membuat tabel, saya mendefinisikan ConstraintTestId kolom untuk menggunakan IDENTITY(1,1) , yang berarti harus dimulai dari 1 dan secara otomatis bertambah 1 dengan setiap sisipan baris.

Tapi sekarang saya akhirnya memasukkan baris pertama saya, nilainya sudah 13. Itu karena IDENTITY kolom bertambah bahkan ketika CHECK kendala menyebabkan INSERT operasi gagal.

Perhatikan bahwa saya membuat beberapa penyisipan tambahan yang gagal saat membuat contoh untuk artikel ini, jadi nilainya telah meningkat ke nilai yang lebih tinggi daripada yang akan Anda dapatkan jika Anda mengikuti langkah demi langkah dengan artikel ini.

Bagaimanapun, mari kita lakukan satu penyisipan yang gagal terakhir, dan kemudian yang berhasil untuk mengonfirmasi ini.

Penyisipan gagal:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 4, '2020-01-02', '2020-02-03' );

Hasil:

Msg 547, Level 16, State 0, Line 1
The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.

Penyisipan berhasil:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 6, '2020-01-02', '2020-02-03' );

SELECT * FROM ConstraintTest;

Hasil:

+--------------------+---------+------------+-------------+------------+
| ConstraintTestId   | Price   | TeamSize   | StartDate   | EndDate    |
|--------------------+---------+------------+-------------+------------|
| 13                 | 1.0000  | 5          | 2020-01-01  | 2020-02-02 |
| 15                 | 2.0000  | 6          | 2020-01-02  | 2020-02-03 |
+--------------------+---------+------------+-------------+------------+

Kita dapat melihat bahwa IDENTITY kolom melompat dari 13 ke 15, jadi jelas bertambah selama penyisipan yang gagal.

Beberapa Batasan Batasan CHECK

Berikut adalah beberapa batasan yang harus diperhatikan saat bekerja dengan CHECK kendala:

  • Kondisi pencarian harus mengevaluasi ke ekspresi Boolean dan tidak dapat mereferensikan tabel lain.
  • Ekspresi tidak boleh berisi tipe data alias.
  • CHECK batasan tidak dapat ditentukan pada teks , nteks , atau gambar kolom.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rencana eksekusi SQL Server — apa itu dan bagaimana itu membantu masalah kinerja?

  2. Kesalahan "Tidak dapat melepaskan pemicu" saat Mencoba Menjatuhkan Pemicu Masuk? Coba ini.

  3. Pernyataan Hapus SQL Server:Cara Menghapus Satu atau Mengalikan Baris dari Tabel

  4. Siklus Melalui Clipboard Ring di SQL Server Management Studio (SSMS) - Tutorial SQL Server / TSQL Bagian 8

  5. Apa itu Format String di SQL Server?