Pada artikel ini, kita akan berbicara tentang kendala CHECK. Kita akan melihat cara menambahkan batasan CHECK ke kolom tabel SQL Server dan mendiskusikan masalah yang mungkin Anda temui saat menggunakan tipe batasan SQL Server ini.
PERIKSA dasar-dasar batasan
PERIKSA kendala hanyalah pernyataan bersyarat (predikat yang mengembalikan TRUE atau FALSE) yang merujuk ke kolom tabel untuk menjaga integritas data. Ketika seseorang menyisipkan data ke dalam kolom atau beberapa kolom dalam satu baris, kendala CHECK mulai beraksi. Mereka mengevaluasi data yang akan dimasukkan. Jika data tidak memenuhi kondisi yang ditentukan dalam batasan CHECK, penyisipan gagal.
Perhatikan contoh berikut:
Hal ini diperlukan untuk menetapkan batasan pada kolom Gaji sehingga hanya menyimpan nilai positif tidak melebihi $150.000. Pernyataan bersyarat akan terlihat sebagai berikut:(Gaji>=0 dan Gaji <=150000). Saat mencoba memasukkan nilai negatif, predikat akan menghasilkan FALSE, dan penyisipan akan gagal.
Dimungkinkan untuk menambahkan batasan CHECK ke satu atau beberapa kolom. Menambahkan batasan CHECK multi-kolom dapat diterapkan di tingkat tabel.
Bekerja dengan batasan CHECK
Cara Membuat Batasan CHECK di SSMS
Di Penjelajah Objek , navigasikan ke tabel yang diperlukan.
Klik kanan Kendala folder dan kemudian c jilat Kendala Baru…
Di panel kanan Periksa Batasan kotak dialog, klik Ekspresi lalu klik tombol elipsis.
Ketik ekspresi kendala PERIKSA ke dalam bidang teks Periksa Ekspresi Kendala kotak dialog. Misalnya, untuk mengizinkan kode pos tujuh digit saja dalam kolom Zip, ekspresinya dapat terlihat sebagai berikut:
Di Desainer Tabel bagian, Anda dapat menyiapkan aturan untuk menegakkan batasan.
PERIKSA Batasan pada CREATE TABLE
Perhatikan contoh berikut:
Diperlukan untuk membuat tabel yang menyimpan data tentang nasabah bank dan mengisinya dengan data uji. Tabel akan menyertakan kolom berikut:Id Pelanggan, Nama Depan, Nama Belakang, Status, Telepon, Kota, Negara Bagian, dan Kode Pos.
Saat mengembangkan tabel, kita harus mempertimbangkan fakta berikut:
Format ZIP dasar terdiri dari lima digit numerik.
Nomor telepon standar Amerika adalah sepuluh digit, seperti (555) 555-1234
Singkatan dua huruf digunakan untuk mewakili divisi politik Amerika Serikat untuk alamat pos, pemrosesan data, singkatan umum, dan tujuan lainnya.
Tugasnya adalah menyediakan konsistensi data untuk tabel. Diperlukan untuk melarang penyisipan 12 digit nomor telepon dan 6 digit zip dll. Untuk melakukan ini, SQL Server memungkinkan kita untuk menambahkan satu atau lebih batasan CHECK untuk setiap kolom tabel.
Di bagian sebelumnya, kita telah memeriksa satu cara untuk membuat batasan CHECK di SSMS. Sekarang, kita akan membahas cara membuat batasan dengan bantuan T-SQL.
Skrip berikut menunjukkan cara membuat batasan CHECK pada kolom Zip:
CREATE TABLE Customers ( Customer_Id tinyint NOT NULL, [First Name] varchar(50), [Last Name] varchar(50), Status varchar(50), Phone tinyint, Address varchar(50), State varchar(50), Zip tinyint, Email varchar(50), [Credit Limit] INT NULL, CONSTRAINT CK_Zip CHECK (Zip LIKE REPLICATE ('[0-9]', 5)) --Check Constraint Condition )
Sekarang, mari kita lihat apa yang kita dapatkan ketika mencoba memasukkan nilai 6 digit ke dalam kolom Zip:
INSERT INTO dbo.Customers (Customer_Id, [First Name], [Last Name], Status, Phone, Address, State, Zip, Email) SELECT 1, 'James', 'Madison', 'Mr', 555-555-1234, 'Madison street, 12', 'LA', 123456, NULL GO
Penyisipan gagal, dan SQL Server menampilkan pencegahan berikut:
Sejauh ini, sangat baik.
Ekspresi KASUS dalam batasan PERIKSA
Asumsikan bahwa bank memiliki aturan bisnis untuk menetapkan batas kredit bagi penduduk negara bagian Louisiana di bawah $150.000. Kami akan menerapkan persyaratan ini dengan menambahkan batasan CHECK ke kolom Batas Kredit:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (State='LA' AND [Credit Limit] <= 150000) GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (1, 'James Black', 'Mr', 5558787, 'LA', 46853, '[email protected]', 120000); GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (2, 'Mark Spencer', 'Mr', 3332244, 'NY', 23487, '[email protected]', 200000); GO
Saat kami menjalankan pernyataan di atas, kami mendapatkan kesalahan berikut:
Pernyataan INSERT bertentangan dengan batasan CHECK. Apa yang salah?
Mari kita lihat kueri lebih dekat. Perhatikan bahwa batasan CHECK hanya mengizinkan nilai 'LA' untuk kolom State. Pada saat yang sama, nilai di kolom Kredit tidak boleh melebihi 150000.
Demikian pula, batasan CHECK tidak mengizinkan penulisan kode status lainnya di kolom.
Dengan demikian, kita perlu mengubah kondisinya. Menurut logika bisnis, bank menyediakan $150.000 dari batas kredit untuk penduduk Louisiana. Pada saat yang sama, nilai ini mungkin berbeda untuk penghuni lain.
Untuk mengimplementasikan kasus ini, kita akan menggunakan klausa CASE di dalam batasan CHECK:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (CASE WHEN State='LA' AND [Credit Limit] <= 150000 THEN 1 ELSE 0 END = 1) GO
Ungkapan ini sepenuhnya memenuhi logika bisnis.
Nilai NULL dalam batasan CHECK
Bank membagi nasabahnya menjadi segmen-segmen. Kolom Status berisi data yang menentukan apakah klien VIP atau reguler. Jumlah maksimum batas kredit untuk pelanggan reguler adalah $200.000. Para VIP dapat menarik $500,000.
Batasan CHECK mungkin terlihat sebagai berikut:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Status_Credit_Limit CHECK (Status = 'VIP' OR Status = 'Regular') GO
Perhatikan bahwa batasan CHECK memungkinkan penyisipan NULL ke dalam kolom State (asalkan tidak ada batasan NOT NULL yang didefinisikan secara eksplisit). Batasan CHECK mengevaluasi nilai dan mengembalikan TRUE atau FALSE. Ini mengevaluasi NULL sebagai UNKNOWN. Oleh karena itu, NULL tidak akan menyebabkan kesalahan. Ini bertentangan dengan predikat dalam klausa WHERE dalam pernyataan SELECT atau UPDATE.
CHECK dan NOCHECK
Dari waktu ke waktu, logika bisnis berubah. Ini menyebabkan modifikasi objek database. Bayangkan sebuah negara memperluas basis kode pos dan menambahkan nilai 6 digit.
Nilai 5 digit lama tidak akan lagi ditetapkan ke area. Namun, mereka masih berlaku untuk yang sudah ada. Dengan demikian, batasan CHECK harus memperhitungkan data yang ada dalam format lama, dan memvalidasi data dalam format baru.
Klausa NOCHECK menyelesaikan masalah ini:
ALTER TABLE Customers WITH NOCHECK ADD CONSTRAINT CK_Zip_Code CHECK (Zip LIKE REPLICATE('[0-9]', 6)); GO
Penyisipan berikut berhasil:
INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (102, 'Jake Harrison', 'VIP', 555-555-1234, 'NY', 123456, '[email protected]', 100000); GO
Saat mencoba memasukkan zip lima digit, mesin menampilkan kesalahan:
KENDALA PERIKSA DBCC
SQL Server menyediakan DBCC CHECKCONSTRAINTS untuk mencari data yang tidak sesuai dengan batasan.
Jika ada masalah integritas database, jalankan DBCC CHECKCONSTRAINTS untuk seluruh database untuk memastikan tidak ada masalah.
Perhatikan bahwa perintah ini memengaruhi kinerja. Oleh karena itu, tidak boleh berjalan sesuai jadwal.
Dimungkinkan untuk menjalankan DBCC CHECKCONSTRAINTS untuk satu kendala, tabel, atau seluruh database.
Dibandingkan dengan perintah pemeriksaan lainnya, DBCC CHECKCONSTRAINTS membutuhkan waktu yang cukup lama untuk menyelesaikan dan menghabiskan sumber daya sistem. Tidak seperti perintah lainnya, CHECKCONSTRAINTS tidak menggunakan snapshot database.
Kesimpulan
PERIKSA kendala menyediakan mekanisme untuk mengevaluasi data sebelum penyisipan. Batasan CHECK dapat merujuk ke satu kolom atau beberapa kolom tabel.
Batasan hanyalah predikat yang menghasilkan TRUE, FALSE, atau UNKNOWN. Jika NULL dimasukkan ke dalam tabel, batasan tidak dilanggar.