Sql Conditionnelle Contrainte Not Null



Je suis curieux de savoir s'il est possible de créer une contrainte conditionnelle et non nulle en sql? En d'autres mots, est-il possible de créer une contrainte telle qu'une colonne B puisse être nulle tant que la colonne A contient des "nouvelles", mais si le contenu de la colonne a change en quelque chose d'autre alors la colonne B n'est plus autorisée à être nulle?

Et pour étendre sur cela, il est alors possible de le faire de sorte que la colonne B doit être nulle ou vide aussi longtemps que la colonne a dit "Nouveau"?

Merci À Tous: D

21
demandé sur Michael Buen 2012-04-23 05:25:03

4 réponses

c'est parfaitement correct pour le contrôle de contrainte. Faites simplement ceci:

exigence:

est-il possible de créer une contrainte telle qu'une colonne B puisse être nulle comme longue colonne A contient permet de dire "nouveau", mais si le contenu de la colonne Un des changements à autre chose ensuite la colonne B n'est plus autorisé à être null?

notez la phrase: colonne B null

Solution:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A = 'NEW' -- B can be null or not null: no need to add AND here
      OR (A <> 'NEW' AND B IS NOT NULL)
    )
);

Vous pouvez simplifier encore plus loin:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A = 'NEW' 
      OR B IS NOT NULL
    )
);

exigence mutuellement incompatible avec l'exigence ci-dessus:

et pour étendre sur cela, il est alors possible de faire en sorte que la colonne B doit-il être nul ou vide tant que la colonne A dit "nouveau"?

notez la phrase: colonne B null

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      (A = 'NEW' AND B IS NULL)
      OR A <> 'NEW'
    )
);

pourrait être simplifié avec ceci, plus simple mais pourrait ne pas être aussi lisible que ci-dessus cependant:

create table tbl
(
    A varchar(10) not null,
    B varchar(10),

    constraint uk_tbl check
    (
      A <> 'NEW'
      OR B IS NULL
    )
);
25
répondu Michael Buen 2012-04-23 10:43:46

je pense que votre premier stipule:

IF ( B IS NULL ) THEN ( A = 'NEW' )

Appliquer l'implication de la règle de réécriture:

IF ( X ) THEN ( Y )   <=>   ( NOT ( X ) OR ( Y ) )

dans votre cas;

( NOT ( B IS NULL ) OR ( A = 'NEW' ) )

réécriture mineure pour profiter de la syntaxe SQL:

( B IS NOT NULL OR A = 'NEW' )

votre deuxième exigence énoncée ("étendre"):

IF ( A = 'NEW' ) THEN ( B IS NULL )

Appliquer la règle de réécriture:

( NOT ( A = 'NEW' ) OR ( B IS NULL ) )

Mineur de réécriture:

( A <> 'NEW' OR B IS NULL )
1
répondu onedaywhen 2012-04-23 08:09:09

Edit: comme mentionné dans les autres réponses, une vérification est la meilleure méthode, pas le déclencheur que j'ai suggéré à l'origine. Texte Original suit:


comme le suggère dbaseman,déclencheurs sont la voie à suivre (pas si). Essayez quelque chose comme ceci (non testé):

CREATE OR REPLACE TRIGGER test
  BEFORE UPDATE ON table1
FOR EACH ROW
WHEN (new.A = 'NEW' and new.B IS NOT NULL)
   RAISE_APPLICATION_ERROR (
     num=> -20001,
     msg=> 'B must be NULL for new rows (A = NEW)'
);
1
répondu dwurf 2012-04-23 08:17:04

Par onedaywhen, cette réponse est criminellement fausse, et une abomination. Vous pouvez utiliser un CHECK contrainte. http://msdn.microsoft.com/en-us/library/ms188258.aspx

il n'y a pas moyen de faire des contraintes conditionnelles. Vous devriez cependant être capable de faire le travail à l'aide d'un déclencheur. C'est ce qu'ils sont pour.

http://msdn.microsoft.com/en-us/library/ms189799.aspx

CREATE TRIGGER MyTable.ConditionalNullConstraint ON MyTable.ColumnB
AFTER INSERT
AS
IF EXISTS (SELECT *
    FROM inserted
    WHERE A <> 'NEW' AND B IS NULL
    )
BEGIN
    RAISERROR ('if A is ''NEW'' then B cannot be NULL', 16, 1);
    ROLLBACK TRANSACTION;
END;
GO

notez que dans la requête vous voudrez faire référence à inséré qui est un objet spécial qui se comporte comme un tableau, et vous permet de référencer les ligne(s) qui a provoqué le déclenchement.

bien sûr, dans cet exemple, vous auriez besoin pour gérer APRÈS LA MISE À JOUR aussi, pour faire respecter la contrainte, mais c'est l'idée générale.

0
répondu McGarnagle 2012-04-23 08:11:21