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.