IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Contrainte de variables NOT NULL


Sujet :

Langage SQL

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    506
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 506
    Par défaut Contrainte de variables NOT NULL
    Bonjour,

    Je crée une table en SQL, j'ai 2 variables de ma table qui doivent être en NOT NULL exclusif, je m'explique:
    - elles ne doivent pas être toutes les 2 null
    - elles ne doivent pas être toutes les 2 not null
    donc si l'une est null l'autre doit être renseigné, et inversement.

    Comment exprimer cette contrainte en SQL lors de la création de la table ?

    Merci,

    Nico

  2. #2
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 212
    Par défaut
    Salut DiverSIG.

    Fusionne tes deux colonnes en une seul et ainsi elle ne sera jamais NULL mais toujours renseignée.
    Si tu dois distinguer leur origine, tu peux ajouter une colonne pour dire à qui appartient la valeur.

  3. #3
    Expert confirmé
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 360
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 360
    Billets dans le blog
    17
    Par défaut
    Tu peux utiliser une contrainte de table et l'opérateur logique XOR.

    Avec MySQL :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    create table test (
        id int primary key auto_increment,
        v1 int,
        v2 int,
        constraint `une seule colonne valorisée` check (v1 is not null xor v2 is not null)
    );
     
    insert into test set v1 = 123, v2 = null; -- OK
    insert into test set v1 = null, v2 = 234; -- OK
    insert into test set v1 = 123, v2 = 234; -- Error Code: 3819. Check constraint 'une seule colonne valorisée' is violated.
    insert into test set v1 = null, v2 = null; -- Error Code: 3819. Check constraint 'une seule colonne valorisée' is violated.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 021
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 021
    Billets dans le blog
    6
    Par défaut
    XOR n'existe pas en SQL.... Mais OR oui !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ...
        constraint CK_ALTERNATE_NOT_NULL check (v1 is null AND v2 is not null OR v1 is not null AND v2 is null)
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 696
    Billets dans le blog
    10
    Par défaut
    Effectivement XOR n'existe que dans le jargon MySQL/MariaDB, mais visiblement certains l'ignorent, j'en veux pour preuve les deux votes négatifs attribués à tort à la réponse de Fred (SQLPro).

  6. #6
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 212
    Par défaut
    Salut à tous.

    Code mysql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE IF NOT EXISTS `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    USE `base`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `test`
    --------------
     
    --------------
    CREATE TABLE `test`
    ( `id`     integer unsigned NOT NULL auto_increment primary key,
      `v1`     integer unsigned     NULL,
      `v2`     integer unsigned     NULL,
       constraint `On_Col` check (v1 is not null xor v2 is not null)
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    insert into `test` (`v1`,`v2`) values (123, null)
    --------------
     
    --------------
    insert into `test` (`v1`,`v2`) values (null,234)
    --------------
     
    --------------
    insert into `test` (`v1`,`v2`) values (234,456)
    --------------
     
    ERROR 3819 (HY000) at line 24: Check constraint 'On_Col' is violated.
    --------------
    insert into `test` (`v1`,`v2`) values (null,null)
    --------------
     
    ERROR 3819 (HY000) at line 25: Check constraint 'On_Col' is violated.
    --------------
    select * from `test`
    --------------
     
    +----+------+------+
    | id | v1   | v2   |
    +----+------+------+
    |  1 |  123 | NULL |
    |  2 | NULL |  234 |
    +----+------+------+
    --------------
    COMMIT
    --------------
     
    Appuyez sur une touche pour continuer...
    Je viens de le tester en reprenant l'exemple de Séb. et a priori le XOR existe bien sous Mysql.
    Sauf qu'il aurait été pertinent de préciser dans quel SGBDR nous devons résoudre cette contrainte.
    Sinon, oui, SQLPRO a raison de souligner que XOR n'existe pas en SQL.

    Pour revenir sur le problème soulevé par DiverSIG, je ne vois pas l'intérêt de créer deux colonnes sachant qu'on peut les fusionner en une seule.
    Ne serait il pas plus simple d'en créer une seule ?
    Mais vu les explications succinctes, il serait bien de détailler pourquoi cette contrainte
    Ne peut on pas faire autrement ?

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 021
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 22 021
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    ...
    Pour revenir sur le problème soulevé par DiverSIG, je ne vois pas l'intérêt de créer deux colonnes sachant qu'on peut les fusionner en une seule.
    Ne serait il pas plus simple d'en créer une seule ?...
    Non, car les deux informations n'ont rien à voir ensemble et il faudrait rajouter une colonne de discrimination pour savoir si c'est une information de v1 ou de v2 qu'il s'agit !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  8. #8
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 696
    Billets dans le blog
    10
    Par défaut
    Bonjour,
    Citation Envoyé par Artemus24 Voir le message
    Mais vu les explications succinctes, il serait bien de détailler pourquoi cette contrainte
    En effet, faute d'en savoir plus, il est difficile de se prononcer sur le "comment".

    Si cette contrainte est la conséquence d'une mauvaise modélisation d'une contrainte de partition de type XT, exclusion et totalité, comme il semble que ce soit le cas, alors rien ne justifie la présence d'attributs, encore moins d'attributs "nullables".
    Rappelons que le marqueur "null" complexifie les tables de décisions (voir ICI), et qu'il est sage de l'éviter autant que faire se peut

  9. #9
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 212
    Par défaut
    @ SQLPRO : en effet, nous ne savons rien des valeurs de ces deux colonnes.

    @ Escartefigue : je suis du même avis, je pense qu'il y a un problème de modélisation.

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 752
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 752
    Par défaut
    Hello,

    Il est tout de même bizarre que sans connaître le SGBD et sa version (CHECK incertains), on puisse avancer sur ce sujet...

    Et si vous voulez taper dans le 1000, il serait intéressant de connaître les noms de colonnes définis par le PO.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  11. #11
    Membre Expert
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    991
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 991
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    il serait intéressant de connaître les noms de colonnes définis par le PO.
    J'ai vécu l'époque où la modélisation objet a mis en évidence que -dans les faits- les méthodes "traditionnelles" passaient à coté des factorisations.
    Par exemple il n'était pas rare d'avoir les informations d'adresse dans la table des fournisseurs et ces mêmes informations dans la table des clients.

    Maintenant il est commun de considérer qu'il faille avoir une table "adresse" commune à tous les tiers.
    Se pose alors la question de comment construire les FK de la table "adresse" vers les tables "fournisseur" et "client".
    La première solution consistant à avoir plusieurs colonnes du type id_fournisseur et id_client ; ainsi les FK déclaratives fonctionnent bien
    Mais, effectivement, comment s'assurer qu'une adresse référence au moins un tiers, qu'il soit fournisseur ou client ?

    Mon exemple ne doit pas être le bon car il n'est pas fondamentalement exclu qu'un fournisseur soit aussi un client, et donc que la même adresse référence les 2 'tiers'
    [EDIT] et le post initial portait sur le XOR, donc soit l'un soit l'autre [\EDIT]
    Mais j'imagine que c'est un truc du genre.

    Note : dans ce que je décris ici je sais bien que l'erreur de conception est de ne pas avoir factorisé la table des tiers.

    Mon petit doigt me dit qu'il va y avoir un joli débat autour de ça
    Espérons que l'auteur du post se manifeste avant de constater qu'on ne répond plus à sa demande ...
    Le savoir est une nourriture qui exige des efforts.

  12. #12
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 494
    Par défaut
    Bonjour,
    De mon point de vue, pour les adresses la liaison doit se faire dans l'autre sens: l'id de l'adresse dans les tables Fournisseur, Client...
    Et si on peut avoir plusieurs adresses pour un même client (livraison, facturation) alors il faut une table de liaison, avec le type d'adresse (dans une autre table, bien sûr).

    Tatayo.

  13. #13
    Membre Expert
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    991
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 991
    Par défaut
    Citation Envoyé par tatayo Voir le message
    De mon point de vue, pour les adresses la liaison doit se faire dans l'autre sens: l'id de l'adresse dans les tables Fournisseur, Client...
    Et si on peut avoir plusieurs adresses pour un même client (livraison, facturation) alors il faut une table de liaison, avec le type d'adresse (dans une autre table, bien sûr).
    Aussi
    Cela inverse la vision de ce qu'est une adresse :
    * est-ce un point d'entrée dont un ou plusieurs tiers dépendent ?
    * est-ce un attribut (simple ou multiple) d'un tiers ?

    Notons que dans cette dernière construction il est pénible, partant d'une ligne adresse, de retrouver la table mère (toujours pareil, s'il y a plusieurs tables de tiers)
    La table de liaison reste une bonne option pour concilier les 2 visions, sans toutefois résoudre la problématique de retrouver les tiers référençant une ligne d'adresse.
    Le savoir est une nourriture qui exige des efforts.

  14. #14
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 696
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Il est possible qu'on s'éloigne du sujet initial.
    Quoi qu'il en soit, raisonner sur les tables est une mauvaise approche, la modélisation doit être le résultat de règles de gestion.

    À partir des règles de gestion validées par le donneur d'ordre, on établit le MCD et les tables ne sont qu'une conséquence du MCD.

    Si l'on considère qu'une même personne peut être à la fois un client, un fournisseur, un mandataire, un délégataire, ce qui n'est pas rare, alors on a tout intérêt à modéliser un type d'entité personne associé à un type d'entité adresse
    Ainsi, on évite les redondances d'adresses pour les personnes qui ont plusieurs rôles.
    Ce faisant, l'adresse peut être considérée comme une entité-type faible de la personne et de ce fait, être identifiée relativement à la personne.
    Le type d'entité personne sera décliné en sous-types personne morale et personne physique les attributs étant spécifiques.
    Par contre, il n'est pas forcément utile de spécialiser les types de personnes. Par exemple, pour savoir si une personne est cliente, il suffit de vérifier si elle a émis des commandes et si elle est fournisseur, alors c'est qu'on lui a envoyé des commandes...

Discussions similaires

  1. Contraint not null
    Par Vince7-7 dans le forum Oracle
    Réponses: 5
    Dernier message: 01/10/2007, 15h50
  2. [9i] Contrainte NOT NULL
    Par Ito dans le forum Administration
    Réponses: 20
    Dernier message: 11/07/2007, 14h13
  3. Ajouter une contrainte NOT NULL à une colonne
    Par abdelghani_k dans le forum Firebird
    Réponses: 1
    Dernier message: 03/06/2007, 17h26
  4. Création de table et contraintes : is null ou is not null ?
    Par GDMINFO dans le forum Langage SQL
    Réponses: 4
    Dernier message: 18/05/2007, 09h09
  5. Ajouter la contrainte NOT NULL a une colone [Firebird 1.5]
    Par crocodingo dans le forum Langage SQL
    Réponses: 2
    Dernier message: 31/01/2004, 19h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo