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 de contrainte


Sujet :

Développement SQL Server

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 15
    Points
    15
    Par défaut Problème de contrainte
    Bonsoir à tous,

    voici mon souci : Je cherche à empêcher qu'un numéro de facture soit utilisé plus d'une fois pour une même année.

    Mon code est donc composé d'une fonction et d'une contrainte check:

    FONCTION :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE FUNCTION checkFNumber(@fnumber varchar(8000), @date datetime) RETURNS INT
    AS
    BEGIN
    	DECLARE @dp int
    	SET @dp = DATEPART(year, @date)
    	RETURN
    	CASE
    		WHEN @fnumber NOT IN (SELECT DISTINCT numero FROM Facture WHERE DATEPART(Year, date_facture) = @dp)
    		THEN 1
    		ELSE 0
    	END
    END
    CONTRAINTE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ALTER TABLE Facture ADD CONSTRAINT UniqueFNumberConstraint CHECK (dbo.checkFNumber(numero, date_facture) = 1)
    Je tente d'insérer une facture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    INSERT INTO Facture(numero, date_facture) VALUES('2', GETDATE());
    Erreur de SQL Server :
    Msg*547, Niveau*16, État*0, Ligne*1
    L'instruction INSERT est en conflit avec la contrainte CHECK "UniqueFNumberConstraint". Le conflit s'est produit dans la base de données "automobile", table "dbo.Facture".
    L'instruction a été arrêtée.
    Il n'y a pourtant aucune données dans la table Facture au moment de l'insertion... comment résoudre ce problème de contrainte?

    Merci d'avance

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Il aurait fallu remplacer par < 2, mais le mieux reste de mettre une contrainte d'unicité, qui est faite exactement pour cela.
    Vous aurez donc besoin d'une colonne calculée qui vous retourne l'année :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE dbo.Facture 
    ADD annee_facture AS (YEAR(date_facture))
    Et la contrainte d'unicité devient alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE dbo.Facture 
    ADD CONSTRAINT UQ_Facture__annee_facture__numero UNIQUE (annee_facture, numero)
    Ce sera en outre bien moins coûteux que d'appeler la fonction

    @++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 16
    Points : 15
    Points
    15
    Par défaut
    Il aurait fallu remplacer par < 2
    Que veux tu dire par ça?

    En tout cas merci, cette autre solution fonctionne à merveille.

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    En fait, < 2 ne fonctionnera pas non plus.
    Donc en supposant que les contraintes d'unicité n'existent pas, il aurait mieux valu écrire :

    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
    CREATE FUNCTION checkFNumber
    	(
    		@fnumber varchar(8000)
    		, @date datetime
    	) 
    RETURNS bit
    AS
    BEGIN
    	DECLARE @result bit
    	SET @result = 1
     
    	IF EXISTS
    	(
    		SELECT	*
    		FROM	dbo.Facture
    		WHERE	date_facture BETWEEN CAST(YEAR(@date) + '0101' AS datetime) AND CAST(YEAR(@date) + '1231' AS datetime)
    		AND	numero = @fnumber
    	)
    	SET @result = 0
     
    	RETURN @result
    END
    Et votre contrainte aurait alors été :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ALTER TABLE dbo.Facture
    ADD CONSTRAINT UniqueFNumberConstraint
    CHECK (dbo.checkFNumber(numero, date_facture) = 1)
    C'est à dire inchangée, mais le comportement correct

    @++

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

Discussions similaires

  1. [SQL] problème de contrainte externe
    Par belakhdarbts10 dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 14/05/2007, 12h15
  2. [Hibernate-MySQL] Problème de contraintes ?!
    Par n@n¤u dans le forum Hibernate
    Réponses: 9
    Dernier message: 03/08/2006, 16h19
  3. Problème de contrainte sur une partie de date (l'année)
    Par shefla dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 11/04/2006, 21h50
  4. Réponses: 5
    Dernier message: 26/10/2005, 14h43
  5. Problème de contrainte dans un "CREATE DOMAIN ..."
    Par VenusX117 dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 15/02/2005, 18h06

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