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

MS SQL Server Discussion :

Trigger ou Valeur par defaut ?


Sujet :

MS SQL Server

  1. #1
    Membre éclairé
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Par défaut Trigger ou Valeur par defaut ?
    Bonjour,

    Dans une table, La colonne codeSC (non null) peut être determinée par la valeur de deux autres colonnes (Etat et IdSC).

    Ce que je souhaite, c'est qu'en cas d'insert où la colonne codeSC serait nulle, pouvoir déterminer automatiquement sa valeur en fonction des deux autres colonnes. (Elles aussi ne peuvent être nulles)

    D'après ce que j'ai pu trouver jusque maintenant, la valeur par défaut ne permettrait pas de faire cela car j'obtiens le message:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Msg*128, Niveau*15, État*1, Ligne*4
    The name "Etat" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
    Si j'ai bien compris, on ne pourrait donc pas spécifier de contrainte default faisant référence à d'autres colonnes.

    D'autre part, j'ai essayer avec un Trigger Instead Of Insert mais le fait que la colonne CodeSC soit nulle provoquerait une erreur avant de déclencher le trigger (Trigger dont j'ignore encore comment modifier la valeur de la colonne CodeSC)

    Si vous aviez une piste...

    Merci pour votre aide

  2. #2
    Membre émérite Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Par défaut
    Bonjour,

    Je croyais que les triggers pouvaient être déclenchés avant la modification (insertion, update, création, suppression). Cela permet par exemple de créer un trigger qui empêche la suppression ou l'insertion.

    J'ai peut-être tord.

    Cordialement,

    Arkhena

  3. #3
    Membre émérite Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Par défaut
    Citation Envoyé par Arkhena Voir le message
    Bonjour,

    Je croyais que les triggers pouvaient être déclenchés avant la modification (insertion, update, création, suppression). Cela permet par exemple de créer un trigger qui empêche la suppression ou l'insertion.

    J'ai peut-être tord.

    Cordialement,

    Arkhena
    J'ai trouvé la doc qui correspond dans la MSDN ici :
    http://msdn.microsoft.com/fr-fr/library/ms189799.aspx

    Il faut faire un trigger INSTEAD OF INSERT. Il est bien précisé dans la doc que si ce trigger fait un INSERT dans la table qu'il surveille il ne s'appellera pas récursivement.

  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 : 43
    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
    Par défaut
    Bonjour,

    Je ne suis pas certain que vous ayez besoin d'un trigger pour réaliser ce type de contraintes : vous pouvez tout simplement écrire une fonction qui fera ce traitement pour vous.

    Supposons que votre codeSC est Etat x IdSC quand codeSC est NULL.
    La fonction serait alors :

    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
    CREATE FUNCTION FnGetCodeSC
    	(
    		@codeSC INT,
    		@Etat INT,
    		@IdSC INT
    	)
    	RETURNS INT
    	WITH SCHEMABINDING
    AS
    BEGIN
    	RETURN
    	(
    		SELECT CASE
    					WHEN @codeSC IS NULL THEN @Etat * @IdSC
    					ELSE @codeSC
    				END
    	)
    END
    Et dans votre table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE maTable
    ADD CONSTRAINT DF_maTable_codeSC DEFAULT (dbo.FnGetCodeSC(codeSC, Etat, IdSC))
    C'est plus élégant, plus puissant, et surtout moins consommateur de ressources.

    Sous SQL Server il n'y a effectivement pas de trigger BEFORE, qui peuvent être "remplacés" comme le montre Arkhena par un trigger INSTEAD OF.

    @++

  5. #5
    Membre émérite Avatar de Arkhena
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 552
    Par défaut
    Effectivement la solution d'elkuset est bien plus élégante!

  6. #6
    Membre éclairé
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Par défaut
    Bonjour,

    Merci pour vos réponses !

    J'ai essayer d'utiliser la solution proposée par elsuket et je n'ai pas réussi.

    En effet, j'ai toujours le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The name CodeSC is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
    En fait, CodeSC fait parti de ma table. Le message ne mentionne pas les autres colonnes mais c'est sans doute que Sql s'arrête à la première erreur rencontrée.

    Si jamais il faut effectivement passer par un Trigger Instead Of Insert, est ce que le code ci dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DECLARE @CodeSC char(10)
    Set @CodeSC = Select CodeSC From Inserted
    Vous semble correct pour récupérer la valeur d'une colonne depuis la pseudo table Inserted ?

    Merci

  7. #7
    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 : 43
    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
    Par défaut
    J'ai essayer d'utiliser la solution proposée par elsuket et je n'ai pas réussi.

    En effet, j'ai toujours le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The name CodeSC IS NOT permitted IN this context. Valid expressions are constants, constant expressions, AND (IN some contexts) VARIABLES. COLUMN names are NOT permitted.
    Désolé, je n'ai pas testé cette instruction, j'ai pensé qu'elle fonctionne, mais il est logique qu'elle ne soit pas autorisée.

    Si jamais il faut effectivement passer par un Trigger Instead Of Insert, est ce que le code ci dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    DECLARE @CodeSC char(10)
    SET @CodeSC = SELECT CodeSC FROM Inserted
    Vous semble correct pour récupérer la valeur d'une colonne depuis la pseudo table Inserted ?
    Non parce que comme tout trigger, il faut qu'il soit ensembliste.

    Voici comment vous pouvez faire :

    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
    CREATE TRIGGER TR_A_I_maTable
    	ON dbo.maTable
    	INSTEAD OF INSERT
    AS
    BEGIN
    	INSERT INTO dbo.maTable
    	(
    		codeSC,
    		Etat,
    		IdSC,
    		autresColonnes
    	)
    	SELECT CASE
    				WHEN codeSC IS NULL THEN Etat * IdSC
    				ELSE codeSC
    			END,
    			Etat,
    			IdSC,
    			autresColonnes
    	FROM INSERTED
    END
    @++

  8. #8
    Membre éclairé
    Profil pro
    Développeur .Net, Administrateur système
    Inscrit en
    Octobre 2003
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur .Net, Administrateur système
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 219
    Par défaut
    Merci pour la réponse

    Ce que je regrette juste, c'est que CodeSC doit autoriser les valeurs nulles pour que cela fonctionne. (Même si cela fait un peu dévier le sens de la valeur par défaut)

    En tous cas Merci encore !

  9. #9
    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 : 43
    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
    Par défaut
    Ce que je regrette juste, c'est que CodeSC doit autoriser les valeurs nulles pour que cela fonctionne.
    Attention : NULL n'est pas une valeur, c'est l'absence de valeur.
    C'est dont une propriété

    Je ne comprends pas pourquoi votre colonne doit est NULLable ...
    Vous avez testé avec celle-ci ne tolérant pas NULL ?

    @++

  10. #10
    Membre émérite
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    623
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 623
    Par défaut
    et sinon une colonne calculée ne ferait pas l'affaire ?
    http://msdn.microsoft.com/fr-fr/library/ms191250.aspx

  11. #11
    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 : 43
    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
    Par défaut
    une colonne calculée ne ferait pas l'affaire ?
    J'y ai pensé aussi mais malheureusement, non, pour la même raison que pour la contrainte de valeur par défaut définie par une fonction : on ne peut pas utiliser une colonne de la table dans la définition de la même colonne calculée.

    @++

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

Discussions similaires

  1. [DBGRID][COLUMN]Valeur par defaut
    Par hamed dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/03/2005, 16h10
  2. VALEUR PAR DEFAUT
    Par Bikey dans le forum Access
    Réponses: 2
    Dernier message: 25/10/2004, 13h57
  3. [Pb : champ Text = pas de valeur par defaut ?]
    Par mat_dum dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 18/08/2003, 12h57
  4. sorte de valeur par defaut
    Par sampq dans le forum Langage SQL
    Réponses: 2
    Dernier message: 25/07/2003, 11h59
  5. Valeur par defaut 'True' dans un champ de type bit
    Par Mouse dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 24/03/2003, 15h26

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