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 :

Insertion via une vue : problème de clef


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    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 : 42
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut Insertion via une vue : problème de clef
    Bonjour,

    Je suis devant une impasse (et je sens que ça va encore être un truc con^^) depuis 30 minutes alors je me tourne vers vous.

    Voici le contexte :

    Dans une DB en cours de développement pour la gestion des vols dans un magasin, je m'aperçois que j'ai oublié la table des types d'antivols. Un antivol n'a, pour le moment, qu'un nom comme propriété mais celui-ci doit être en 2 langues.

    J'ai donc les tables suivantes :
    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
    CREATE TABLE [dbo].[T_TYPE_ANTITHEFT_TNT](
        [TNT_ID] [int] IDENTITY(1,1) NOT NULL,
     CONSTRAINT [PK_T_TYPE_ANTITHEFT_TAN] PRIMARY KEY CLUSTERED 
    (
        [TNT_ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    CREATE TABLE [dbo].[T_TYPE_ANTITHEFT_LNG_TAL](
        [TNT_ID] [int] NOT NULL,
        [LNG_ID] [tinyint] NOT NULL,
        [TAL_LIB] [varchar](50) NOT NULL,
     CONSTRAINT [PK_T_TYPE_ANTITHEFT_LNG_TAL] PRIMARY KEY CLUSTERED 
    (
        [TNT_ID] ASC,
        [LNG_ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    ALTER TABLE [dbo].[T_TYPE_ANTITHEFT_LNG_TAL]  WITH CHECK ADD  CONSTRAINT [FK_T_TYPE_ANTITHEFT_LNG_TAL_T_LANGUAGE_LNG] FOREIGN KEY([LNG_ID])
    REFERENCES [dbo].[T_LANGUAGE_LNG] ([LNG_ID])
    GO
     
    ALTER TABLE [dbo].[T_TYPE_ANTITHEFT_LNG_TAL] CHECK CONSTRAINT [FK_T_TYPE_ANTITHEFT_LNG_TAL_T_LANGUAGE_LNG]
    GO
     
    ALTER TABLE [dbo].[T_TYPE_ANTITHEFT_LNG_TAL]  WITH CHECK ADD  CONSTRAINT [FK_T_TYPE_ANTITHEFT_LNG_TAL_T_TYPE_ANTITHEFT_TNT] FOREIGN KEY([TNT_ID])
    REFERENCES [dbo].[T_TYPE_ANTITHEFT_TNT] ([TNT_ID])
    GO
     
    ALTER TABLE [dbo].[T_TYPE_ANTITHEFT_LNG_TAL] CHECK CONSTRAINT [FK_T_TYPE_ANTITHEFT_LNG_TAL_T_TYPE_ANTITHEFT_TNT]
    GO
    Le tout regroupé à l'aide de la vue que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    CREATE VIEW [dbo].[V_TYPE_ANTITHEFT_VTA] 
    AS
    SELECT
            TNT.TNT_ID, TAL1.TAL_LIB AS 'VTA_LIB_FR', TAL2.TAL_LIB AS 'VTA_LIB_NL'
    FROM
            DBO.T_TYPE_ANTITHEFT_TNT TNT
                LEFT JOIN DBO.T_TYPE_ANTITHEFT_LNG_TAL TAL1
                    ON    TNT.TNT_ID = TAL1.TNT_ID
                    AND TAL1.LNG_ID = 1
                LEFT JOIN DBO.T_TYPE_ANTITHEFT_LNG_TAL TAL2
                    ON    TNT.TNT_ID = TAL2.TNT_ID
                    AND TAL2.LNG_ID = 2
    GO
    Vu qu'on a une vue portant sur plusieurs tables, il me faut donc des triggers pour les opérations insert/update/delete.

    Pour update et delete, pas de souci.

    Par contre, je bloque pour l'insert.

    Les seules solutions qui me viennent sont des solutions qui ne fonctionne que pour l'insertion d'une ligne à la fois... Or on travaille avec des ensembles...

    Voici ce qui me bloque :

    Pour insérer une ligne dans la table T_TYPE_ANTITHEFT_TNT, j'utilise le code INSERT INTO dbo.T_TYPE_ANTITHEFT_TNT DEFAULT VALUES;. Mais pour plusieurs lignes ?


    Une fois les insertions faites dans cette table, comment je fais l'association avec mes libellés ? Je sens un problème pour m'assurer que des libellés FR et NL d'une même ligne vont bien recevoir le même TNT_ID.

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Pour du mono-ligne, je ferai comme ça :
    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
    CREATE TRIGGER tgioi_V_TYPE_ANTITHEFT_VTA on [dbo].[V_TYPE_ANTITHEFT_VTA] 
    INSTEAD OF INSERT
    AS
    BEGIN
        DECLARE @TNT_ID integer;
        DECLARE @VTA_LIB_FR varchar(50);
        DECLARE @VTA_LIB_NL varchar(50);
        select @VTA_LIB_FR = [VTA_LIB_FR]
             , @VTA_LIB_NL = [VTA_LIB_NL]
          from inserted;
        insert into dbo.T_TYPE_ANTITHEFT_TNT default values;
        set @TNT_ID = SCOPE_IDENTITY();
        if @VTA_LIB_FR is not null
          insert into DBO.T_TYPE_ANTITHEFT_LNG_TAL (TNT_ID, LNG_ID, TAL_LIB)
          values (@TNT_ID, 1, @VTA_LIB_FR);
        if @VTA_LIB_NL is not null
          insert into DBO.T_TYPE_ANTITHEFT_LNG_TAL (TNT_ID, LNG_ID, TAL_LIB)
          values (@TNT_ID, 2, @VTA_LIB_NL);
    END;
    GO
    Mais effectivement ça ne fonctionne pas sur un insert multi-lignes.

  3. #3
    Membre expérimenté
    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 : 42
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Oui j'avais déjà une solution similaire mais je ne peux pas utiliser cela sans devoir plaider la folie passagère par la suite

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Pour la version multi-lignes :
    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
    CREATE TRIGGER tgioi_V_TYPE_ANTITHEFT_VTA on [dbo].[V_TYPE_ANTITHEFT_VTA] 
    INSTEAD OF INSERT
    AS
    BEGIN
        SET NOCOUNT ON;
        DECLARE @TNT_ID integer;
        DECLARE @VTA_LIB_FR varchar(50);
        DECLARE @VTA_LIB_NL varchar(50);
        DECLARE my_Cursor CURSOR FAST_FORWARD FOR SELECT [VTA_LIB_FR], [VTA_LIB_NL] FROM INSERTED
     
        OPEN my_Cursor
        FETCH NEXT FROM my_Cursor INTO @VTA_LIB_FR, @VTA_LIB_NL;
     
        WHILE @@FETCH_STATUS = 0 
        BEGIN 
     
            insert into dbo.T_TYPE_ANTITHEFT_TNT default values;
            set @TNT_ID = SCOPE_IDENTITY();
            if @VTA_LIB_FR is not null
              insert into DBO.T_TYPE_ANTITHEFT_LNG_TAL (TNT_ID, LNG_ID, TAL_LIB) values (@TNT_ID, 1, @VTA_LIB_FR);
            if @VTA_LIB_NL is not null
              insert into DBO.T_TYPE_ANTITHEFT_LNG_TAL (TNT_ID, LNG_ID, TAL_LIB) values (@TNT_ID, 2, @VTA_LIB_NL);
     
        FETCH NEXT FROM my_Cursor INTO @VTA_LIB_FR, @VTA_LIB_NL;
        END;
        CLOSE my_Cursor;
        DEALLOCATE my_Cursor;
        SET NOCOUNT OFF;
    END;
    GO
    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
    insert into [dbo].[V_TYPE_ANTITHEFT_VTA] ([VTA_LIB_FR], [VTA_LIB_NL]) values ('AAAA', 'BBBB')
     
    insert into [dbo].[V_TYPE_ANTITHEFT_VTA] ([VTA_LIB_FR]) values ('CCCC')
    insert into [dbo].[V_TYPE_ANTITHEFT_VTA] ([VTA_LIB_NL]) values ('DDDD')
     
    insert into [dbo].[V_TYPE_ANTITHEFT_VTA] ([VTA_LIB_FR], [VTA_LIB_NL])
    select 'F1', 'N1' union all
    select 'F2', 'N2' union all
    select 'F3', null union all
    select null, 'N4';
     
    select * from [dbo].[V_TYPE_ANTITHEFT_VTA]
     
    TNT_ID      VTA_LIB_FR                                         VTA_LIB_NL
    ----------- -------------------------------------------------- --------------------------------------------------
    1           AAAA                                               BBBB
    2           CCCC                                               NULL
    3           NULL                                               DDDD
    4           F1                                                 N1
    5           F2                                                 N2
    6           F3                                                 NULL
    7           NULL                                               N4
    Ne soyez pas effrayez, il n'y a rien de vraiment nucléaire dedans.
    Par contre, j'ai recherché ci et là pour le curseur, je ne sais pas si c'est la solution la plus efficace.

  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 010
    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 010
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    Voici ce qui me bloque :

    Pour insérer une ligne dans la table T_TYPE_ANTITHEFT_TNT, j'utilise le code INSERT INTO dbo.T_TYPE_ANTITHEFT_TNT DEFAULT VALUES;. Mais pour plusieurs lignes ?
    Faire un produit cartésien (CROSS JOIN) avec la table inserted.
    Ou encore attribuez vous une plage de clef avec DBCC CHECKIDENT et distribuez la dans les différentes tables

    Une fois les insertions faites dans cette table, comment je fais l'association avec mes libellés ? Je sens un problème pour m'assurer que des libellés FR et NL d'une même ligne vont bien recevoir le même TNT_ID.
    Par exemple en stockant vos clefs obtenues par réajustement de l'auto incrément dans une variable table...

    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. Trigger d'insertion sur une vue
    Par Cirtadz dans le forum PL/SQL
    Réponses: 40
    Dernier message: 19/02/2009, 12h56
  2. Trier une vue, problème de CAML querry.
    Par lightbulb dans le forum SharePoint
    Réponses: 5
    Dernier message: 04/02/2009, 16h32
  3. Réponses: 2
    Dernier message: 15/10/2008, 15h49
  4. Réponses: 0
    Dernier message: 20/02/2008, 11h55
  5. [9i] Eviter un table access full via une vue
    Par Débéa dans le forum SQL
    Réponses: 10
    Dernier message: 25/10/2006, 23h09

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