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

Développement SQL Server Discussion :

Problème d'établissement d'une contrainte


Sujet :

Développement 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 Problème d'établissement d'une contrainte
    Hello,

    Je rencontre des problèmes pour établir une contrainte CHECK. Lorsque j'exécute l'ordre ALTER TABLE pour l'ajouter, j'ai un message d'erreur disant que l'ordre entre en conflit avec la contrainte que je tente d'ajouter.

    Le contexte :

    J'ai les tables suivantes (je les ai édulcorées pour ne garder que les colonnes servant dans les clefs ou contraintes histoire d'alléger un peu) :

    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
    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
    --contient la liste des promo
    CREATE TABLE [S_PROMO].[T_PROMO_PRM](
        [PRM_ID] [int] IDENTITY(-2147483648,1) NOT NULL,
        [PRM_STARTDATE] [date] NOT NULL,
        [PRM_ENDDATE] [date] NOT NULL,
        [PRM_STARTTIME] [time](0) NOT NULL,
        [PRM_ENDTIME] [time](0) NOT NULL,
        [PRM_DESC] [varchar](50) NOT NULL,
        [PRT_ID] [tinyint] NOT NULL,
     CONSTRAINT [PK_T_PROMO_PRM] PRIMARY KEY CLUSTERED 
    (
        [PRM_ID] ASC
    )
    ) ON [PRIMARY]
     
     
    --contient le détail des promos pour la marchandise propre
    CREATE TABLE [S_PROMO].[T_DETAIL_OWN_DTO](
        [DTO_ID] [int] IDENTITY(-2147483648,1) NOT NULL,
        [PRM_ID] [int] NOT NULL,
        [DEP_ID] [smallint] NOT NULL,
        [BRA_ID] [int] NOT NULL,
        [DTO_PERCENT] [decimal](4, 2) NOT NULL,
        [PCT_ID] [tinyint] NOT NULL,
     CONSTRAINT [PK_T_DETAIL_OWN_DTO] PRIMARY KEY CLUSTERED 
    (
        [DTO_ID] ASC
    ),
     CONSTRAINT [AK_T_DETAIL_OWN_DTO] UNIQUE NONCLUSTERED 
    (
        [PRM_ID] ASC,
        [DEP_ID] ASC,
        [BRA_ID] ASC,
        [DTO_PERCENT] ASC,
        [PCT_ID] ASC
    )
    ) ON [PRIMARY]
    GO
     
    ALTER TABLE [S_PROMO].[T_DETAIL_OWN_DTO]  WITH CHECK ADD  CONSTRAINT [FK_DTO_TO_PRM] FOREIGN KEY([PRM_ID])
    REFERENCES [S_PROMO].[T_PROMO_PRM] ([PRM_ID])
    GO
     
    --contient les listes d'articles en promo
    CREATE TABLE [S_PROMO].[T_PRODUCT_LIST_OWN_PLO](
        [DTO_ID] [int] NOT NULL,
        [PLO_BARCODE] [char](13) NOT NULL,
        [PLO_INCLUSIVE] [bit] NOT NULL,
     CONSTRAINT [PK_T_PRODUCT_LIST_OWN_PLO] PRIMARY KEY CLUSTERED 
    (
        [DTO_ID] ASC,
        [PLO_BARCODE] ASC
    )
    ) ON [PRIMARY]
     
    ALTER TABLE [S_PROMO].[T_PRODUCT_LIST_OWN_PLO]  WITH CHECK ADD  CONSTRAINT [FK_PLO_TO_DTO] FOREIGN KEY([DTO_ID])
    REFERENCES [S_PROMO].[T_DETAIL_OWN_DTO] ([DTO_ID]) ON DELETE CASCADE
    GO
    On a donc une première table qui contient le "header" des promos. Juste un nom et des dates de début et de fin.
    La deuxième table indique sur quelle marque (BRA_ID), dans quel rayon (DEP_ID) il y a une promo et quel est le pourcentage de cette promo (DTO_PERCENT).*
    La dernière table indique les articles qui sont concernés par la promo de la 2e table (seulement si PCT_ID indique qu'il s'agit d'une liste)

    * PCT_ID indique le type de pourcentage, cela peut-être automatique (cad sur tous les articles de la marque dans le rayon) ou sur seulement sur une liste d'articles.

    La contrainte :

    Le but de la contrainte est d'empêcher qu'un article se retrouve dans deux listes sous une même promo.

    J'ai donc écrit la fonction suivante :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    CREATE FUNCTION S_PROMO.UF_CHECK_DOUBLE_EAN_OWN (@BARCODE CHAR(13), @DTO_ID INT) RETURNS BIT
    AS
    BEGIN
        DECLARE @RESULT BIT;
        DECLARE @COUNT    INT;
        DECLARE @PRM_ID INT;
     
        SELECT    @PRM_ID = PRM_ID
        FROM    S_PROMO.T_DETAIL_OWN_DTO
        WHERE    DTO_ID = @DTO_ID;
     
        SELECT    @COUNT = COUNT(*)
        FROM    S_PROMO.T_PRODUCT_LIST_OWN_PLO PLO
                    INNER JOIN S_PROMO.T_DETAIL_OWN_DTO DTO
                        ON    PLO.DTO_ID = DTO.DTO_ID
        WHERE    DTO.PRM_ID = @PRM_ID
            AND PLO.PLO_BARCODE = @BARCODE;
     
        IF @COUNT = 1
            SET @RESULT = 0
        ELSE    
            SET @RESULT = 1
     
        RETURN @RESULT;
    END
    Et l'ordre de modification e table qui va avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE S_PROMO.T_PRODUCT_LIST_OWN_PLO ADD CONSTRAINT CK_DOUBLE_PROMO CHECK (S_PROMO.UF_CHECK_DOUBLE_EAN_OWN(PLO_BARCODE, DTO_ID)=0);
    Et j'ai donc le message suivant :
    Msg 547, Level 16, State 0, Line 2
    The ALTER TABLE statement conflicted with the CHECK constraint "CK_DOUBLE_PROMO". The conflict occurred in database "INNO_ADMIN", table "S_PROMO.T_PRODUCT_LIST_OWN_PLO".
    Mes tests :

    Avant d'écrire le code ci-dessus pour établir cette contrainte, j'avais testé comme 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    CREATE SCHEMA S_TEST;
    GO
     
    CREATE TABLE S_TEST.T_TEST_TST(
            TST_ID    INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
            TST_CODE CHAR(4) NOT NULL)
    GO
     
    CREATE FUNCTION S_TEST.UF_CHECK_DOUBLE_CODE(@CODE CHAR(4)) RETURNS BIT
    AS
    BEGIN
        DECLARE @RESULT BIT;
        DECLARE @COUNT INT;
     
        SELECT    @COUNT = COUNT(*)
        FROM    S_TEST.T_TEST_TST
        WHERE    TST_CODE = @CODE
     
        IF @COUNT = 1
            SET @RESULT = 0
        ELSE
            SET @RESULT = 1
     
        RETURN @RESULT;
    END
    GO
     
    ALTER TABLE S_TEST.T_TEST_TST WITH CHECK ADD CONSTRAINT CK_DOUBLE_CODE CHECK (S_TEST.UF_CHECK_DOUBLE_CODE(TST_CODE)=0);
    Avec ce code, si je fais INSERT INTO S_TEST.T_TEST_TST(TST_CODE) VALUES ('1234'), l'insertion se fait bien la 1e fois mais pas les fois suivantes. Cela assure donc bien qu'il n'y ai qu'une ligne avec un code.**

    ** Ici j'aurai pu me contenter d'ajouter un index unique sur la colonne TST_CODE mais vu que dans le cas concret, je dois faire référence à une autre table, j'ai directement tester en écrivant une fonction.

    En conclusion :

    Quelqu'un pourrait-il m'aiguiller sur ce que je fais de travers ??
    J'ai bien sûr vérifier et il n'y a pas de barcode en double pour une même promo dans la table concerné par la contrainte. Du coup, je reste perplexe sur le pourquoi de ce message d'erreur. J'imagine bien qu'il doit y avoir une faille dans ma fonction mais je ne vois pas où .

    Merci d'avance à ceux qui prendront la peine de lire ce pavé.
    Kropernic

  2. #2
    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 continué à fouiller et il semblerait que, effectivement, il y a déjà des doublons dans la table des produits...

    Comme quoi, sql server est quand même bien fait ^^.
    Kropernic

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

Discussions similaires

  1. Problème de supression d'une contrainte issue d'une table inconnue
    Par berceker united dans le forum Adaptive Server Enterprise
    Réponses: 1
    Dernier message: 05/01/2016, 17h38
  2. MCD: Problème dans une contrainte
    Par 0redd dans le forum Merise
    Réponses: 8
    Dernier message: 22/08/2011, 17h31
  3. Problème dans l'établissement d'une requête
    Par M€lK!oR dans le forum Requêtes
    Réponses: 7
    Dernier message: 16/12/2009, 15h11
  4. problème lors de l'ajout d'une contrainte
    Par belgariel dans le forum SQL
    Réponses: 4
    Dernier message: 04/11/2009, 11h17
  5. Problème pour réactiver une contrainte en novalidate
    Par AnkyFive dans le forum Administration
    Réponses: 2
    Dernier message: 17/06/2009, 11h21

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