it-swarm-eu.dev

Zkontrolujte omezení pouze jeden ze tří sloupců není null

Mám tabulku (SQL Server), která obsahuje 3 typy výsledků: FLOAT, NVARCHAR (30) nebo DATETIME (3 samostatné sloupce). Chci zajistit, aby v kterémkoli daném řádku měl výsledek pouze jeden sloupec a ostatní sloupce jsou NULL. Jaké je nejjednodušší omezení kontroly, jak toho dosáhnout?

Kontext pro to se snaží dovybavit schopnost zachytit nečíselné výsledky do existujícího systému. Přidání dvou nových sloupců do tabulky s omezením, které zabrání více než jednomu výsledku na řádku, bylo nejúspornějším přístupem, ne nutně správným.

Aktualizace: Litujeme, datový typ snafu. Bohužel jsem nezamýšlel typy výsledků označené jako interpretované jako datové typy SQL Server, pouze obecné pojmy, nyní opravené.

65
David Clarke

Trik by měl udělat následující:

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

Pravděpodobně budete muset provést tři testy v rámci omezení, jeden test pro každý pár, který chcete být null, a jeden pro sloupec, který by neměl být null:

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

Zde je řešení PostgreSQL používající vestavěné funkce pole :

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

PRO POSTGRESQL

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

Převedeme sloupec na boolean s IS NOT NULL ( true nebo false ), poté vrhněte do :: celé číslo ( 0 nebo 1 ) Potom můžeme použít aritmetické operátory

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