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

Administration SQL Server Discussion :

J'ai un doute sur les contraintes CHECK


Sujet :

Administration SQL Server

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut J'ai un doute sur les contraintes CHECK
    Hello,

    Une rapide question au sujet des contraintes CHECK car un doute m'habite.

    Est-ce que le check est fait avant ou après l'insertion de la/des ligne/s ?

    Un cas concret...

    Soit la table suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE T(
        ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
        CODE SMALLINT NOT NULL,
        STARTDATE DATE NOT NULL,
        ENDDATE DATE NOT NULL)
    GO
    ALTER TABLE T WITH CHECK ADD CONSTRAINT AK_T UNIQUE (CODE, STARTDATE)
    GO
    Jusque là, pas de souci. Maintenant, en plus de cette contrainte d'unicité, je voudrais ajouter une contrainte check qui interdit le chevauchement de période pour un même code.
    Je crée donc une fonction pour vérifier cela qui donne ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE FUNCTION S_HP.UF_CHECK_OVERLAPPING_CODE(@CODE SMALLINT, @START DATE, @END DATE) RETURNS BIT
    AS
    BEGIN
        DECLARE @RESULT BIT
     
        IF EXISTS (    SELECT    1
                    FROM    T
                    WHERE    CODE = @CODE
                        AND dbo.OVERLAPS(@START, @END, STARTDATE, ENDDATE) = 1)
            SET @RESULT = 1
        ELSE
            SET @RESULT = 0
        RETURN @RESULT
    END
    GO
    Maintenant, si le check se fait après l'insertion, le résultat sera toujours 1 et il faut que j'ajoute une branche dans la clause WHERE pour exclure la ligne en cours de check sur base de son ID. Je pourrais le faire d'office et ne pas me poser de question mais j'aime bien faire les choses correctement.

    Merci d'avance.
    Kropernic

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    ...
    Maintenant, si le check se fait après l'insertion, le résultat sera toujours 1 et il faut que j'ajoute une branche dans la clause WHERE pour exclure la ligne en cours de check sur base de son ID. Je pourrais le faire d'office et ne pas me poser de question mais j'aime bien faire les choses correctement.

    Merci d'avance.
    Une contrainte CHECK retourne True (Vraie) lorsque la condition qu'elle vérifie n'est pas False et ce pour n'importe quelle ligne de la table. Si une table venant d'être créée ne comporte aucune ligne, les éventuelles contraintes CHECK sur cette table sont considérées comme valides. Cette situation peut produire des résultats inattendus, comme l'illustre l'exemple suivant.

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    CREATE TABLE CheckTbl (col1 int, col2 int);
    GO
    CREATE FUNCTION CheckFnctn()
    RETURNS int
    AS 
    BEGIN
       DECLARE @retval int
       SELECT @retval = COUNT(*) FROM CheckTbl
       RETURN @retval
    END;
    GO
    ALTER TABLE CheckTbl
    ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 );
    GO

    - La contrainte CHECK ajoutée spécifie que la table CheckTbl doit contenir au moins une ligne. Toutefois, comme la table ne contient aucune ligne par rapport à laquelle vérifier la condition de cette contrainte, l'instruction ALTER TABLE réussit.

    Il suffit ensuite de changer la valeur 1 par une valeur strictement supérieur à 1 (exemple (dbo.CheckFnctn() >= 2 ) et il ne sera plus possible d'insérer aucune ligne dans la table CheckTbl , dès lors qu'on part d'une table vide !!!!

    - Par ailleurs, les contraintes CHECK ne sont pas validées pendant les instructions DELETE. Par conséquent, l'exécution d'instructions DELETE sur des tables avec certains types de contraintes de vérification peuvent produire des résultats inattendus. Imaginons, par exemple, les instructions suivantes exécutées sur la table CheckTbl.

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO CheckTbl VALUES (10, 10)
    GO
    DELETE CheckTbl WHERE col1 = 10;
    L'instruction DELETE réussit, même si la contrainte CHECK spécifie que la table CheckTbl doit comporter au moins 1 ligne.

    Pour revenir à votre question initiale, il faut considérer que le contrainte doit être vérifiée à tout instant AVANT et APRES Insertion. Dans votre cas, partant du principe que la contrainte était vérifiée AVANT insertion, il faut que la dite contrainte soit et reste vérifiée également APRES insertion.
    Il vous faudra donc impérativement rajouter dans la clause WHERE ID <> @Id pour exclure la ligne en cours.

    A+
    "Une idée mal écrite est une idée fausse !"
    http://hamid-mira.blogspot.com

  3. #3
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Merci pour cette réponse détaillée
    Kropernic

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Avoir un message personnalisé sur une contrainte check
    Par brunoSCP dans le forum Débuter
    Réponses: 5
    Dernier message: 29/09/2016, 14h30
  2. Doute sur les expressions régulières
    Par pierrot10 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 15/05/2009, 10h12
  3. question sur les contraintes
    Par shadowmoon dans le forum Langage SQL
    Réponses: 6
    Dernier message: 31/05/2005, 08h47
  4. [SQL]Questions sur les contraintes ?
    Par patmaba dans le forum Oracle
    Réponses: 3
    Dernier message: 24/02/2005, 15h12
  5. Question sur les contraintes d'intégrités
    Par eGGyyS dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 27/04/2004, 13h51

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