it-swarm.asia

Periksa kendala hanya satu dari tiga kolom yang bukan nol

Saya memiliki tabel (SQL Server) yang berisi 3 jenis hasil: FLOAT, NVARCHAR (30), atau DATETIME (3 kolom terpisah). Saya ingin memastikan bahwa untuk setiap baris yang diberikan, hanya satu kolom yang memiliki hasil dan kolom lainnya adalah NULL. Apa kendala pemeriksaan paling sederhana untuk mencapai ini?

Konteks untuk ini adalah mencoba untuk memperbaiki kemampuan untuk menangkap hasil non-numerik ke dalam sistem yang ada. Menambahkan dua kolom baru ke tabel dengan kendala untuk mencegah lebih dari satu hasil per baris adalah pendekatan yang paling ekonomis, tidak harus yang benar.

Pembaruan: Maaf, tipe data snafu. Sayangnya saya tidak bermaksud tipe hasil yang ditunjukkan ditafsirkan sebagai tipe data SQL Server, hanya istilah umum, diperbaiki sekarang.

65
David Clarke

Yang berikut harus melakukan trik:

CREATE TABLE MyTable (col1 FLOAT NULL, col2 NVARCHAR(30) NULL, col3 DATETIME NULL);
GO

ALTER TABLE MyTable
ADD CONSTRAINT CheckOnlyOneColumnIsNull
CHECK 
(
    ( CASE WHEN col1 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col2 IS NULL THEN 0 ELSE 1 END
    + CASE WHEN col3 IS NULL THEN 0 ELSE 1 END
    ) = 1
)
GO
78

Anda mungkin perlu melakukan tiga tes dalam batasan, satu tes untuk setiap pasangan yang Anda inginkan menjadi nol dan satu untuk kolom yang seharusnya bukan nol:

ALTER TABLE table
ADD CONSTRAINT CK_one_is_null
CHECK (
     (col1 IS NOT NULL AND col2 IS NULL AND col3 IS NULL)
  OR (col2 IS NOT NULL AND col1 IS NULL AND col3 IS NULL) 
  OR (col3 IS NOT NULL AND col1 IS NULL AND col2 IS NULL)
);
24
mrdenny

Inilah solusi PostgreSQL menggunakan fungsi array bawaan :

ALTER TABLE your_table
ADD chk_only_one_is_not_null CHECK (array_length(array_remove(ARRAY[col1::text, col2::text, col3::text], NULL), 1) = 1);
5
CrEOF

NTUK POSTGRESQL

CHECK( (col_1 IS NOT NULL)::integer + (col_2 IS NOT NULL)::integer + ... = 1 )

Kami mengonversi kolom menjadi boolean dengan BUKAN NULL ( true atau false ), lalu dilemparkan ke :: integer ( 0 atau 1 ) Kemudian kita dapat menggunakan operator aritmatika

= 1  //must one row is not null  
<= 1 //only one row can be not null
1
Mendes