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 :

Query Merge difficulté d'écriture du DELETE


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 176
    Par défaut Query Merge difficulté d'écriture du DELETE
    Bonne rencontre,

    Je me casse les dents sur une query alors je viens chercher l’inspiration auprès de vous.

    Voici le cas :

    J’ai une table customers_category (Idcustomer,idcategory).
    je reçois des fichiers xml que je stocke dans la base de données et je fais ensuite des query sur le champ xml.

    Le fichier contient par exemple :

    idcustomer 55 avec idcategory 4, idcategory 7 mais aucune entrée sur l’idcustomer 100

    La table customers_category contient par exemple :

    idcustomer 55, idcategory 4
    idcustomer 55, idcategory 10
    idcustomer 100, idcategory 1
    idcustomer 100, idcategory 2


    J’ai essayé de travailler avec du MERGE, pour l’insert et l’update pas de problème.

    Une fois que j’ajoute le DELETE, il me vide complètement ma table customers_category. Ma condition de filtre n’est pas bonne mais je ne sais pas si j’ai les valeurs nécessaires pour y arriver.

    Voici le code procédure stockée.

    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    USE [ZoneCustomerExchange]
    GO
    /****** Object:  StoredProcedure [dbo].[SetDataCustomersCategory]    Script Date: 08-06-17 10:47:31 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Description: Permet d'ajouter des catégories à un client
    -- =============================================
    ALTER PROCEDURE [dbo].[SetDataCustomersCategory]
    	-- Add the parameters for the stored procedure here
     
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
       	DECLARE @idFile int
    	DECLARE @NameFile varchar(50)
     
    	--Customers
    	DECLARE XmlData CURSOR FOR 
    						SELECT  
    							[dbo].[FilesXML].IDFilesXML,
    							[dbo].[FilesXML].NameFile   
    						FROM [dbo].[FilesXML]
    						WHERE 
    							[dbo].[FilesXML].Parite = 1 
    						AND [dbo].[FilesXML].FKSource = 1
    						AND [dbo].[FilesXML].DateExplore IS NULL
    						AND [dbo].[FilesXML].Type = 'CatCustomers'			
    						ORDER BY [dbo].[FilesXML].IDFilesXML
       OPEN XmlData
       FETCH XmlData INTO @idFile,@NameFile   
     
     
       WHILE @@FETCH_STATUS = 0
    	BEGIN
     
    		MERGE [dbo].[customers_category] AS target
    			USING (
    				SELECT
    				  pref.value('(email/text())[1]', 'varchar(255)') as email,
    				  sref.value('(text())[1]', 'varchar(50)') as CAT,
    				  @NameFile as NameFile,
    				  1 as IDSource,
    				  [dbo].[customers].[idcustomer],
    				  [dbo].[customers].[IDSourceIdAgency],
    				  [dbo].[category].idcategory
    				FROM  
    					FilesXML CROSS APPLY
    					XmlData.nodes('/Root/customer') AS customer(pref)
    					CROSS APPLY
    					 pref.nodes('category/idcategory') AS CAT(sref)
    				INNER JOIN [dbo].[customers]
    				ON [dbo].[customers].email =  pref.value('(email/text())[1]', 'varchar(255)')   
    				INNER JOIN [dbo].[category]
    				ON [dbo].[category].IDSourceIdCategory = sref.value('(text())[1]', 'varchar(50)')  AND [dbo].[category].IDSourceIdAgency = [dbo].[customers].[IDSourceIdAgency]
    				WHERE 
    					FilesXML.IDFilesXML = @idFile
    				AND pref.value('(email/text())[1]', 'varchar(255)')  <> 'NULL'
    				AND  sref.value('(text())[1]', 'varchar(50)')   <> 'NULL'
    			) as Source
    			ON (target.[Idcategory] = Source.idcategory AND target.Idcustomer =  Source.idcustomer)
    		WHEN MATCHED THEN
     
    			 UPDATE SET
    				target.NameFile = Source.NameFile
     
    		WHEN NOT MATCHED BY target THEN 
     
    	    		INSERT 	(Idcategory,Idcustomer,NameFile	)
    				VALUES (
    				 Source.idcategory
    				,Source.idcustomer
    				,Source.NameFile
    				)
     
    		WHEN NOT MATCHED AND target.Idcustomer =  Source.idcustomer THEN		
    				DELETE
     
    		OUTPUT $action, inserted.*, deleted.*;
     
    		FETCH XmlData INTO @idFile, @NameFile
    	END
       CLOSE XmlData
       DEALLOCATE XmlData
     
     
     
     
    END
    Merci de votre aide.
    Raphaël.

  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 : 44
    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,

    Pourriez-vous donner la structure de la table FilesXML et un exemple de document XML svp ?
    Par ailleurs, il est bizarre que vous utilisez un curseur, alors que le MERGE peut réaliser l'opération pour toutes les lignes d'un seul coup.
    C'est d'ailleurs ce pour quoi le moteur de base de données est conçu et optimisé.

    @++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 176
    Par défaut
    Bonjour,

    Le curseur, c'est pour aller chercher tous les fichiers qui n'ont pas encore été parcourus.

    Mais maintenant que vous le dites, j'aurais probablement pu aller chercher tous les fichiers avec un

    WHERE FilesXML.IDFilesXML IN (SELECT ...)

    En fait, je suis en train de revoir tout mon code car j'avais tendance à utiliser des curseurs par ignorance.

    La structure de la table que vous demandez :


    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
    USE [ZoneCustomerExchange]
    GO
     
    /****** Object:  Table [dbo].[FilesXML]    Script Date: 08-06-17 15:00:55 ******/
    SET ANSI_NULLS ON
    GO
     
    SET QUOTED_IDENTIFIER ON
    GO
     
    SET ANSI_PADDING ON
    GO
     
    CREATE TABLE [dbo].[FilesXML](
    	[IDFilesXML] [int] IDENTITY(1,1) NOT NULL,
    	[NameFile] [varchar](50) NULL,
    	[Type] [varchar](50) NULL,
    	[XmlData] [xml] NULL,
    	[DateImport] [datetime] NULL,
    	[DateExplore] [datetime] NULL,
    	[Parite] [bit] NULL CONSTRAINT [DF__FilesXML__Parite__1FCDBCEB]  DEFAULT ((0)),
    	[FKSource] [int] NULL,
     CONSTRAINT [PK__FilesXML__BA034CBEECEB0F29] PRIMARY KEY CLUSTERED 
    (
    	[IDFilesXML] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
     
    GO
     
    SET ANSI_PADDING OFF
    GO
     
    ALTER TABLE [dbo].[FilesXML]  WITH CHECK ADD  CONSTRAINT [FK__FilesXML__FKSour__2A4B4B5E] FOREIGN KEY([FKSource])
    REFERENCES [dbo].[Source] ([IDSource])
    GO
     
    ALTER TABLE [dbo].[FilesXML] CHECK CONSTRAINT [FK__FilesXML__FKSour__2A4B4B5E]
    GO
    Un extrait du XML que je reçois.

    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
     
     
      <customer>
        <idcustomer>50000</idcustomer>
        <idAgency>PY50000U</idAgency>
        <email>test@test.be</email>
        <titel>NULL</titel>
        <firstname>Testeur</firstname>
        <name>System</name>
        <gender>1</gender>
        <language>1</language>
        <birthdate>29/12/1972</birthdate>
        <adress>Rue du test 176</adress>
        <zip>1000</zip>
        <cityfr>Liberty City</cityfr>
        <citynl>Liberty City</citynl>
        <countryisocode>BE</countryisocode>
        <mobilephone>NULL</mobilephone>
        <fax>NULL</fax>
        <expirationdatepassport>NULL</expirationdatepassport>
        <createddate>NULL</createddate>
        <createdby>NULL</createdby>
        <ModifiedDate>NULL</ModifiedDate>
        <ModifiedBy>NULL</ModifiedBy>
        <Active>1</Active>
        <Automation>1</Automation>
        <DoesNotWantMailing>0</DoesNotWantMailing>
        <HasDied>0</HasDied>
        <Blocked>1</Blocked>
        <category>
          <idcategory>{8D726ED7-D878-40EC-B2E9-19272A906810}</idcategory>
          <idcategory>{C1ADAEA1-3910-417A-BAA7-24AF017F3EE1}</idcategory>
          <idcategory>{CB833840-1AE2-4B85-9951-8B0E587D7FFE}</idcategory>
          <idcategory>{02DF3659-4451-4342-92EC-B5C09534A041}</idcategory>
          <idcategory>{AE222D12-7AA4-4F6E-82E7-B5DED17E45F1}</idcategory>
        </category>
        <subscription/>
        <interests/>
      </customer>
    Merci.

  4. #4
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    Bonjour,

    Ce que je trouve etrange également, c'est que votre procédure compile, mais surtout s’exécute.
    Êtes-vous certains d'avoir posté le bon code ?

    Car vous avez deux clauses WHEN NOT MATCHED BY TARGET :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    WHEN NOT MATCHED BY target THEN 
    [...] 
    WHEN NOT MATCHED AND target.Idcustomer =  Source.idcustomer THEN
    dans la deuxième, en l'absence de précision, c'est BY TARGET qui est pris en compte, or il n'est pas possible de mettre deux fois cette clause dans une commande MERGEMais il n'est pas non plus possible de mettre un DELETE dans cette clause.
    donc quelque chose ne va pas dans le code que vous avez posté. La procédure n'aurait pas pu s’exécuter ainsi écrite...

    je pense que la deuxième devrait être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHEN NOT MATCHED BY SOURCE AND target.Idcustomer =  Source.idcustomer THEN

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 176
    Par défaut
    WHEN NOT MATCHED BY SOURCE AND target.Idcustomer = Source.idcustomer THEN
    C'est exact. J'ai probablement du retirer le BY source lors de mon dernier test avant de poster. Désolé.

    Le résultat par contre expliqué reste inchangé car c'était la situation de base.

    Merci pour vos réponses.

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Par défaut
    En fait il ne manque pas que le BY SOURCECar dans la condition qui suit, il est fait référence à la table source : AND target.Idcustomer = Source.idcustomer THEN, ce qui n'est pas valide non plus (puisque justement il n'y a pas de ligne correspondante dans la source ! ).

    De toute évidence, le code que vous avez posté n'est pas celui qui pose problème, on va donc avoir du mal à vous aider.
    Postez la requête qui a provoqué le comportement que vous décrivez (suppression de toutes les lignes).

Discussions similaires

  1. [MySQL] difficulté en suppression DELETE
    Par marcel marie dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 14/01/2009, 13h34
  2. Delete et query
    Par tarmo57 dans le forum Débuter
    Réponses: 2
    Dernier message: 04/10/2008, 11h24
  3. SQL Merge into - delete ne marche pas
    Par Javotte dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/06/2008, 09h29
  4. Aide sur Query et Delete
    Par flo291288 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 12/06/2008, 08h09
  5. Écriture dans un DBgrid quand utilise un query comme dataset
    Par dcayou dans le forum Bases de données
    Réponses: 3
    Dernier message: 13/07/2004, 22h22

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