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 :

Insertion données par Trigger


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Etudiant (domaine de prédilection java)
    Inscrit en
    Mars 2012
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant (domaine de prédilection java)
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2012
    Messages : 71
    Par défaut Insertion données par Trigger
    Bonjour à tous,
    Dans une table de ma base de données existe un champ dont j'aimerais déduire la valeur des valeurs des autres champs de la table.
    Structure de la table: Documents(id_doc, id_type_doc, nom_affaire, indice).
    Le champ id_doc doit être constitué des 3 premières lettres du nom affaire + indice+id_type_doc.
    Pour ce faire, j'ai pensé à la création d'un trigger à l'insertion des autres données dans la table.
    ça donne quelque chose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TRIGGER PAC.dbo.insertion
    AFTER INSERT ON PAC.dbo.Document
    FOR EACH ROW
    BEGIN 
    	INSERT INTO NEW.id_doc
    	SELECT SUBSTRING(NEW.nom_affaire,0,4)+CAST(NEW.id_type_doc AS NVARCHAR)+
    	CAST(NEW.indice AS NVARCHAR);
    END
    Les "casts" c'est pour éviter les erreurs dues à la conversion implicite directe des types nvarchar en int,
    les "+" c'est pour la concaténation, et le "substring" pour la récupération des 3 premières lettres du nom affaire.
    Seulement lorsque je vais dans la rubrique"modification des 200 premières lignes", il se passe rien lorsque j'entre les données dans les autres colonnes. J'ai pensé que peut-être je devrais remplacer "AFTER" par "Before", mais là encore il se passe rien.
    A quel niveau ai-je commis une erreur? merci..

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 002
    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 002
    Billets dans le blog
    6
    Par défaut
    1) il vous faut un trigger INSERT et UPDATE, car vos colonnes peuvent être mise à jour
    2) utilisez pour ce faire un trigger est stupide, car il existe des colonnes calculées, persistantes ou non
    3) en faisant cela vous violez la première forme normale (mélange de 3 in formations dans une même colonnes)
    4) comme votre clef est composé de données déjà existantes, vous générez de la redondance. Or dans une base de données, faire de la redondance est stupide à tous niveau : possibilité d'anomalies transactionnelle et augmentation artificielle du volume des données.
    5) Un NVARCHAR sans longueur c'est stupide. Il faut donner la longueur
    6) si cet id_doc constitue votre clef, vous ne pourrez pas faire cette immonde salade.
    7) enfin quand on veut de l'aide on respecte la charte de postage en publiant le DDL de votre table : http://www.developpez.net/forums/d96...vement-poster/


    Bref, catastrophique pour les performances !


    Exemple de trigger
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TRIGGER E_DOC_IU
    AFTER INSERT, UPDATE
    ON dbo.Document
    BEGIN
    UPDATE T
    SET    id_doc = SUBSTRING(nom_affaire,0,4) 
                  + CAST(id_type_doc AS NVARCHAR(32))
                  + CAST(indice AS NVARCHAR(32));
    FROM   dbo.Document
    WHERE  id_doc IS NULL;
    A +

    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/ * * * * *

  3. #3
    Membre confirmé
    Homme Profil pro
    Etudiant (domaine de prédilection java)
    Inscrit en
    Mars 2012
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant (domaine de prédilection java)
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2012
    Messages : 71
    Par défaut
    Merci SQLpro pour cette réponse diligente et précise.
    -->En ce qui concerne l'application de la charte(notamment en ce qui concerne le code), je m'appliquerai davantage lors de mes prochains posts.
    -->J'ai bien essayé les colonnes calculées au départ, mais à chaque fois j'ai eu un message d'erreur du genre 'vos donnez contiennent des erreurs, voulez vous annuler?' lors de l'édition de la formule.
    -->En fait, id_doc n'est pas destiné à être la clé primaire, je me suis certainement mal exprimé, elle devrait s'appeler plutot "nom_document" parce qu'un nom de document est codifié de cette manière.
    En ce qui concerne le problème de 1FN, je vois pas très bien où se situe le problème...

    Merci encore pour le code, je le teste tout de suite.

  4. #4
    Membre confirmé
    Homme Profil pro
    Etudiant (domaine de prédilection java)
    Inscrit en
    Mars 2012
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant (domaine de prédilection java)
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2012
    Messages : 71
    Par défaut
    MADRE DE DIOS! ça maarche!
    SqlPro, après t'avoir relu, j'ai réessayé par la colonne calculée,avec résultat persistant, et là comme par magie....ça fonctionne parfaitement, je n'y comprend plus rien. C'est exactement le même code que j'ai rentré, et qui pourtant faisait bouder le moteur.

    Voici la Structure de ma table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE [dbo].[Document](
    	[id_doc]  AS ((substring([nom_affaire],(0),(4))+CONVERT([nvarchar],[id_type_doc],0))+CONVERT([nvarchar],[indice],0)) PERSISTED,
    	[id_type_doc] [int] NOT NULL,
    	[numéro] [int] NULL,
    	[indice] [nchar](10) NOT NULL,
    	[nom_affaire] [nvarchar](50) NOT NULL,
    	[iden] [int] IDENTITY(1,1) NOT NULL,
     CONSTRAINT [PK_Document] PRIMARY KEY CLUSTERED 
    (
    	[iden] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    Ceci dit, j'ai pas encore testé la formule avec le trigger...

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    22 002
    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 002
    Billets dans le blog
    6
    Par défaut
    En fait tout ceci ne sert à rien, car tu peut faire cela dans une vue....

    On ne devrait jamais attaquer les bases de données par les tables, mais uniquement avec les vues...

    Exemple :

    1) la table : Documents(id_type_doc, numero, indice, nom_affaire, iden)
    donc par d'id_doc
    ET PAS D'ACENT DANS LES NOMS DES OBJETS !!!

    2) la vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE VIEW V_Documents
    AS
    SELECT SUBSTRING(nom_affaire,0,4) 
                  + CAST(id_type_doc AS NVARCHAR(32))
                  + CAST(indice AS NVARCHAR(32)) AS id_doc,
           id_type_doc, numero, indice, nom_affaire, iden
    FROM    Documents
    Vous pouvez faire des INSERT, UPDATE, DELETE dans cette vue, sauf pour les données calculées (id_doc) évidemment !

    A +

    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/ * * * * *

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/05/2011, 09h25
  2. [MySQL] insertion donnée saisi par HTML
    Par restart dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 13/12/2009, 09h47
  3. RAISE_APPLICATION_ERROR + INSERT déclenchés par trigger
    Par petit_crabe dans le forum PL/SQL
    Réponses: 2
    Dernier message: 26/06/2007, 15h11
  4. Insertion des données par le QueryDataSet !
    Par hugobob dans le forum JDBC
    Réponses: 3
    Dernier message: 20/02/2007, 14h01
  5. Insertion de données par un formulaire
    Par despeludo dans le forum Access
    Réponses: 5
    Dernier message: 07/02/2007, 22h29

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