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

Cari Tahu apakah Batasan CHECK adalah Level Kolom atau Level Tabel di SQL Server (Contoh T-SQL)

Saat Anda membuat CHECK batasan di SQL Server, Anda bahkan mungkin tidak memikirkan apakah itu batasan level tabel atau batasan level kolom.

CHECK tingkat tabel batasan berlaku untuk tabel, sedangkan batasan tingkat kolom berlaku untuk kolom tertentu. Dengan tingkat tabel CHECK kendala, itu adalah baris yang diperiksa saat memeriksa data. Dengan CHECK tingkat kolom kendala, ini adalah kolom khusus yang dicentang.

Umumnya Anda akan tahu apakah batasan yang Anda buat adalah batasan level tabel atau level kolom menurut definisi yang Anda berikan. Jika hanya satu kolom yang diperiksa dalam ekspresi, itu akan menjadi kendala tingkat kolom. Jika tidak, itu akan menjadi batasan tingkat tabel.

Tapi bagaimana Anda tahu jika kendala yang ada adalah tingkat kolom atau tingkat tabel?

Anda dapat menjalankan salah satu contoh kode di bawah ini untuk menentukan apakah batasan yang ada adalah tingkat kolom atau tingkat tabel. Ini mengambil semua CHECK batasan untuk database saat ini, tetapi Anda selalu dapat menggunakan WHERE klausa untuk mempersempitnya menjadi batasan tertentu.

Contoh 1 – Kueri Dasar

Berikut adalah kueri sederhana yang mengembalikan informasi dasar tentang semua CHECK batasan dalam database saat ini.

Di sini, saya menanyakan sys.check_constraints tampilan sistem (yang mengembalikan baris untuk setiap objek yang merupakan CHECK kendala, dengan sys.objects.type = 'C' ). Saya hanya mengembalikan empat kolom (tetapi silakan kembalikan kolom sebanyak yang Anda suka).

SELECT 
  Name,
  OBJECT_NAME(parent_object_id) AS 'Table',
  parent_column_id,
  Definition
FROM sys.check_constraints;

Hasil:

+-----------------+----------------+--------------------+----------------------------------------+
| Name            | Table          | parent_column_id   | Definition                             |
|-----------------+----------------+--------------------+----------------------------------------|
| chkPrice        | ConstraintTest | 2                  | ([Price]>(0))                          |
| chkValidEndDate | ConstraintTest | 0                  | ([EndDate]>=[StartDate])               |
| chkTeamSize     | ConstraintTest | 3                  | ([TeamSize]>=(5) AND [TeamSize]<=(20)) |
| chkJobTitle     | Occupation     | 3                  | ([JobTitle]<>'Digital Nomad')          |
+-----------------+----------------+--------------------+----------------------------------------+

Cara tercepat untuk menentukan batasan mana yang merupakan batasan tingkat tabel adalah dengan mencari nol ( 0 ) di parent_column_id kolom. Apa pun dengan nol adalah CHECK tingkat tabel paksaan. Nilai bukan nol menunjukkan bahwa ini adalah CHECK tingkat kolom batasan yang ditentukan pada kolom dengan nilai ID yang ditentukan.

Jadi dalam contoh ini ada tiga batasan level kolom dan satu batasan level tabel.

Perhatikan bahwa ada dua batasan dengan parent_column_id yang sama (3), bagaimanapun, kedua batasan ini berasal dari tabel yang berbeda. 3 mengacu pada kolom ketiga dari tabel masing-masing.

Seperti yang disebutkan, jika Anda hanya menginginkan info tentang batasan tertentu, gunakan WHERE klausa:

SELECT 
  Name,
  OBJECT_NAME(parent_object_id) AS 'Table',
  parent_column_id,
  Definition
FROM sys.check_constraints
WHERE name = 'chkPrice';

Hasil:

+----------+----------------+--------------------+---------------+
| Name     | Table          | parent_column_id   | Definition    |
|----------+----------------+--------------------+---------------|
| chkPrice | ConstraintTest | 2                  | ([Price]>(0)) |
+----------+----------------+--------------------+---------------+

Contoh 2 – Tingkatkan Kueri

Kita dapat memperbaiki contoh sebelumnya dengan mengembalikan nama kolom induk, bukan hanya ID-nya. Tentu saja, ini akan mengembalikan nama kolom hanya untuk batasan tingkat kolom. Untuk batasan tingkat tabel, NULL akan dikembalikan.

SELECT 
  cc.name AS 'Constraint',
  o.name AS 'Table',
  ac.name AS 'Column',
  cc.Definition AS 'Constraint Definition'
FROM sys.check_constraints cc
LEFT OUTER JOIN sys.objects o
  ON cc.parent_object_id = o.object_id
LEFT OUTER JOIN sys.all_columns ac
  ON cc.parent_column_id = ac.column_id
  AND cc.parent_object_id = ac.object_id;

Hasil:

+-----------------+----------------+----------+----------------------------------------+
| Constraint      | Table          | Column   | Constraint Definition                  |
|-----------------+----------------+----------+----------------------------------------|
| chkPrice        | ConstraintTest | Price    | ([Price]>(0))                          |
| chkValidEndDate | ConstraintTest | NULL     | ([EndDate]>=[StartDate])               |
| chkTeamSize     | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) |
| chkJobTitle     | Occupation     | JobTitle | ([JobTitle]<>'Digital Nomad')          |
+-----------------+----------------+----------+----------------------------------------+

Contoh 3 – Peningkatan Lebih Lanjut

Mari kita ubah kuerinya lagi:

SELECT 
  cc.name AS 'Constraint',
  cc.is_disabled AS 'Disabled?',
  CASE WHEN cc.parent_column_id = 0
    THEN 'Table-level'
    ELSE 'Column-level'
    END AS 'Table/Column',
  o.name AS 'Table',
  ISNULL(ac.name, '(n/a)') AS 'Column',
  cc.Definition AS 'Constraint Definition'
FROM sys.check_constraints cc
LEFT OUTER JOIN sys.objects o
  ON cc.parent_object_id = o.object_id
LEFT OUTER JOIN sys.all_columns ac
  ON cc.parent_column_id = ac.column_id
  AND cc.parent_object_id = ac.object_id;

Hasil:

+-----------------+-------------+----------------+----------------+----------+----------------------------------------+
| Constraint      | Disabled?   | Table/Column   | Table          | Column   | Constraint Definition                  |
|-----------------+-------------+----------------+----------------+----------+----------------------------------------|
| chkPrice        | 0           | Column-level   | ConstraintTest | Price    | ([Price]>(0))                          |
| chkValidEndDate | 0           | Table-level    | ConstraintTest | (n/a)    | ([EndDate]>=[StartDate])               |
| chkTeamSize     | 0           | Column-level   | ConstraintTest | TeamSize | ([TeamSize]>=(5) AND [TeamSize]<=(20)) |
| chkJobTitle     | 0           | Column-level   | Occupation     | JobTitle | ([JobTitle]<>'Digital Nomad')          |
+-----------------+-------------+----------------+----------------+----------+----------------------------------------+

Jadi sekarang saya memiliki teks "Tingkat kolom" atau "Tingkat tabel" yang dikembalikan, tergantung yang mana.

Saya juga menggunakan ISNULL() berfungsi untuk mengubah nilai NULL menjadi “(n/a)”.

Dan saya juga telah menambahkan is_disabled kolom ke daftar, untuk berjaga-jaga jika ada kendala yang dinonaktifkan. Anda selalu dapat memberikan kolom ini perlakuan yang sama seperti parent_column_id kolom dan tunjukkan “Ya” atau “Tidak” atau “Diaktifkan” atau “Dinonaktifkan” atau serupa.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tanggal / Stempel waktu untuk merekam saat catatan ditambahkan ke tabel?

  2. Bagaimana cara menerapkan LIMIT dengan SQL Server?

  3. 4 Tips untuk Menjalankan Diagnostik SQL Server

  4. Bagaimana menjalankan Prosedur Tersimpan dari Laravel

  5. Agregasi string yang dikelompokkan / LISTAGG untuk SQL Server