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 :

S'assurer de la fin d'insert ?


Sujet :

MS SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut S'assurer de la fin d'insert ?
    Bonjour,

    J'ai un script qui me permet de faire plusieurs INSERT dans différentes tables et j'aimerais m'assurer que lorsque commence un INSERT le premier soit fini.

    Je ne peux pas utiliser GO car je déclare une variable au début de mon script.
    Sinon il faudrait que je déclare cette variable avant chaque INSERT.

    Comment puis je faire ?

    Exemple de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Declare @variable 
    set @variable = 2
     
    set indentity_insert toto on
    INSERT ...
    set indentity_insert toto off
     
    set indentity_insert tata on
    INSERT ...
    set indentity_insert tata off
     
    ...

  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 : 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
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Il n'y a pas besoin de s'en assurer puisque les instructions sont implicitement exécutées comme transactions dans l'ordre où vous les spécifiez.

    @++

  3. #3
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    Ha ok ... bizarre puisque j'ai eu une erreur d'insertion de donnée à cause d'une FK qui correspondait à l'insertion d'avant sachant que celle ci s'était bien passé.

    Et en reprenant juste l'insertion qui plantait et en l’exécutant dans une autre fenêtre je n'ai pas eu de soucis ...

  4. #4
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Est ce que tu peux nous donner la définition des tables ainsi le code que tu exécutes et qui poserait problème ?

  5. #5
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    Alors voici les tables qui posent problème.
    Tout d'abord le script de création de ces 2 tables, sans compter les index.

    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 table Donnee
     (
       IdDonnee int identity(1,1),
       ValeurChaine nvarchar(255) null,
       ValeurEntier int null,
       ValeurReel float(13) null,
       ValeurBooleen bit null,
       constraint PK_Donnee primary key (IdDonnee)
     ) 
    go
     
    create table Famille
     (
       IdFamille int identity(1,1),
       IdDonneeLibelle int not null,
       Nom nvarchar(50) not null,
       constraint PK_Famille primary key (IdFamille)
     ) 
    go
    La Foreign Key correspondante, sur celle ou j'ai un soucis lors de l'insertion des données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    alter table Famille 
         add constraint FK_Famille_Donnee foreign key (IdDonneeLibelle) 
                   references Donnee (IdDonnee)
    go
    Le script me permettant d’insérer les données :
    Pour info je vais chercher les données sources sur un serveur lié que je rapatrie ensuite sur ma base locale.
    J'ai pas mal de table remplie de cette manière ...

    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
     
     
    /* Import de la donnée servant de libellé */
    set identity_insert Donnee on
     
    	insert into Test.dbo.Donnee (
    		IdDonnee, 
    		ValeurBooleen, 
    		ValeurChaine, 
    		ValeurEntier, 
    		ValeurReel
    	)
    	select distinct(IDDonnee), ValeurBooleen, ValeurChaine, ValeurEntier, ValeurReel 
    	from ServLie.BaseSource.dbo.Donnee d
    	inner join ServLie.BaseSource.dbo.Famille f on f.IDDonneeLibelle = d.IDDonnee
    	inner join ServLie.BaseSource.dbo.ProduitPays pp on pp.IdFamille = f.IdFamille
    	inner join ServLie.BaseSource.dbo.ProduitPaysProduitClient pppc on pppc.IDProduitPays = pp.IDProduitPays
    	where pppc.IDProduitClient = @idProduitClient
    	and f.IDDonneeLibelle not in (
    		select IdDonnee 
    		from Test.dbo.Donnee
    	)
     
    IF @@ERROR <> 0
        PRINT N'ERREUR : Donnee - Famille '
    ELSE 
    	PRINT N'TABLE : Donnee - Famille -> OK'
     
    set identity_insert Donnee off
     
    /* Import de la Famille */
    set identity_insert Famille on
     
    	insert into Test.dbo.Famille (
    		IdFamille,
    		IdDonneeLibelle,
    		Nom
    	)
    	select distinct(f.IdFamille), f.IDDonneeLibelle, f.Nom
    	from ServLie.BaseSource.dbo.Famille f
    	inner join ServLie.BaseSource.dbo.ProduitPays pp on pp.IdFamille = f.IdFamille
    	inner join ServLie.BaseSource.dbo.ProduitPaysProduitClient pppc on pppc.IDProduitPays = pp.IDProduitPays
    	where pppc.IDProduitClient = @idProduitClient
    	and f.IdFamille not in (
    		select IdFamille 
    		from Test.dbo.Famille
    	)
     
    IF @@ERROR <> 0
        PRINT N'ERREUR : Famille '
    ELSE 
    	PRINT N'TABLE : Famille -> OK'
     
    set identity_insert Famille off

  6. #6
    Rédacteur
    Avatar de WOLO Laurent
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Mars 2003
    Messages
    2 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Congo-Brazzaville

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 2 741
    Points : 4 414
    Points
    4 414
    Par défaut
    Je pense qu'il faut que tu commences par des insert dans la table famille avant de faire des insert dans la table donnes.
    C'est ca ton problème.

  7. #7
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    Bin non justement, vu que je ne détruis pas mes contraintes de FK, les données doivent d'abord être présente dans la table Donnee pour ensuite remplir la table Famille qui a une colonne IdDonneeLibelle qui pointe vers les données IdDonnee de la table Donnee.

    Si je fais le contraire, je vais avoir une erreur d'insertion (FK_Famille_Donnee) me disant que les données IdDonneeLibelle pointent vers aucune données de la table Donnee ...

    Ce qui me parait bizarre c'est que je fais les mêmes insertions sur d'autres tables et cela pose aucun problème ... d'où mon incompréhension de l'erreur !

  8. #8
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Vous avez effectivement raison, c'est l'inverse

    Donc cela signifie que l'INSERT que vous réalisez dans la table dbo.Donnee ne contient pas la valeur de IdDonneeLibelle dont vous avez besoin pour réaliser l'INSERT dans la table dbo.Famille.

    Il me semble que la valeur manquante est donnée dans le libellé de l'erreur sur violation de clé étrangère
    Si ce n'est pas le cas, pour trouver les valeurs qui "manquent", il vous faut exécuter :

    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
     
    ;WITH
    	DONNEE AS
    	(
    		SELECT		d.IDDonneeLibelle
    		FROM		ServLie.BaseSource.dbo.Donnee AS d
    		INNER JOIN	ServLie.BaseSource.dbo.Famille AS f
    					ON f.IDDonneeLibelle = d.IDDonnee
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPays AS pp
    					ON pp.IdFamille = f.IdFamille
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPaysProduitClient AS pppc
    					ON pppc.IDProduitPays = pp.IDProduitPays
    		WHERE		pppc.IDProduitClient = @idProduitClient
    		AND		f.IDDonneeLibelle NOT IN
    				(
    					SELECT	IdDonnee 
    					FROM	Test.dbo.Donnee
    				)
    	)
    	, FAMILLE AS
    	(
    		SELECT		f.IDDonneeLibelle
    		FROM		ServLie.BaseSource.dbo.Famille AS f
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPays AS pp
    					ON pp.IdFamille = f.IdFamille
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPaysProduitClient AS pppc
    					ON pppc.IDProduitPays = pp.IDProduitPays
    		WHERE		pppc.IDProduitClient = @idProduitClient
    		AND		f.IdFamille NOT IN
    				(
    					SELECT	IdFamille 
    					FROM	Test.dbo.Famille
    				)
    	)
    SELECT		DISTINCT *
    FROM		DONNEE AS D
    LEFT JOIN	FAMILLE AS F
    			ON D.IDDonneeLibelle = F.IDDonneeLibelle
    WHERE		D.IDDonneeLibelle IS NULL
    @++

  9. #9
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    En fait j'ai déjà chercher les IdDonneeLibelle qui manque et je n'en trouve pas via des Not Exists ...
    Et en ré-exécutant le script, l'insertion se passe sans problème ...

    En fait l'insertion ds la table Donnee se passe bien, j'ai bien 31 insertions
    Et quand je regarde dans la famille, j'ai bien ces 31 ID ...

    Mais je vais tester les requêtes récursives pour voir !

  10. #10
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    Je viens d'essayer la requête récursive ... aucun résultats ...

    *PAN*

  11. #11
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    En fait, je me demande si je n’atteins pas le cache mémoire ou je ne sais quoi qui fait que ça plante ....

    Parce que franchement je vois pas d'où peut venir l'erreur ...

  12. #12
    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
    Points : 12 371
    Points
    12 371
    Par défaut
    Attention : une expression de table commune n'est pas forcément récursive, et c'est le cas des deux que je vous ai proposé.

    Je me suis trompé dans la demi-jointure gauche, excusez-moi :

    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
    ;WITH
    	DONNEE AS
    	(
    		SELECT		d.IDDonneeLibelle
    		FROM		ServLie.BaseSource.dbo.Donnee AS d
    		INNER JOIN	ServLie.BaseSource.dbo.Famille AS f
    					ON f.IDDonneeLibelle = d.IDDonnee
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPays AS pp
    					ON pp.IdFamille = f.IdFamille
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPaysProduitClient AS pppc
    					ON pppc.IDProduitPays = pp.IDProduitPays
    		WHERE		pppc.IDProduitClient = @idProduitClient
    		AND		f.IDDonneeLibelle NOT IN
    				(
    					SELECT	IdDonnee 
    					FROM	Test.dbo.Donnee
    				)
    	)
    	, FAMILLE AS
    	(
    		SELECT		f.IDDonneeLibelle
    		FROM		ServLie.BaseSource.dbo.Famille AS f
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPays AS pp
    					ON pp.IdFamille = f.IdFamille
    		INNER JOIN	ServLie.BaseSource.dbo.ProduitPaysProduitClient AS pppc
    					ON pppc.IDProduitPays = pp.IDProduitPays
    		WHERE		pppc.IDProduitClient = @idProduitClient
    		AND		f.IdFamille NOT IN
    				(
    					SELECT	IdFamille 
    					FROM	Test.dbo.Famille
    				)
    	)
    SELECT		DISTINCT *
    FROM		FAMILLE AS F
    LEFT JOIN	DONNEE AS D
    			ON D.IDDonneeLibelle = F.IDDonneeLibelle
    WHERE		D.IDDonneeLibelle IS NULL
    Cela vous retourne-t-il quelques valeurs ?

    @++

  13. #13
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    J'ai lancé la requête après mon script d'insertion et donc après plantage !

    J'ai bien des réponses ...

    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
     
    3636	NULL
    3763	NULL
    3812	NULL
    3873	NULL
    4681	NULL
    4918	NULL
    4997	NULL
    5046	NULL
    5635	NULL
    5660	NULL
    5837	NULL
    6532	NULL
    8153	NULL
    8685	NULL
    9926	NULL
    10563	NULL
    11422	NULL
    11456	NULL
    13146	NULL
    14372	NULL
    14643	NULL
    16005	NULL
    19021	NULL
    19108	NULL
    20017	NULL
    20206	NULL
    20377	NULL
    20482	NULL
    20542	NULL
    20691	NULL
    22118	NULL
    Si je comprends bien, je retrouve bien des valeurs IDDonneeLibelle dans la table Famille qui ne correspondent pas aux valeurs des IdDonnee de la table Donnee ?

    Mais ces valeurs sont bien présente dans ma table Donnee précédemment remplies et donc dans le serveur lié ...

    Je comprends plus rien !

  14. #14
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    En fait je suis sur une piste ...

    Lors de ma deuxième insertion de données dans la table Famille, je cherche à insérer les données dans la table depuis la table source en tenant compte des données déjà présentes.
    Et c'est lors de ce test que j'obtiens une erreur !!

    Je retourne bien 31 lignes ...
    Je cherche les données dans la base source qui ne sont pas encore insérées dans la table de la base test.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	SELECT DISTINCT(IDDonnee), ValeurBooleen, ValeurChaine, ValeurEntier, ValeurReel 
    	FROM ServLie.BaseSource.dbo.Donnee d
    	INNER JOIN ServLie.BaseSource.dbo.Famille f ON f.IDDonneeLibelle = d.IDDonnee
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPays pp ON pp.IdFamille = f.IdFamille
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPaysProduitClient pppc ON pppc.IDProduitPays = pp.IDProduitPays
    	WHERE pppc.IDProduitClient = @idProduitClient
    	AND f.IDDonneeLibelle NOT IN (
    		SELECT IdDonnee 
    		FROM Test.dbo.Donnee
    	)
    Maintenant je fais la même chose pour les données Familles et j'obtiens 51 lignes !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT DISTINCT(f.IdFamille), f.IDDonneeLibelle, f.Nom
    	FROM ServLie.BaseSource.dbo.Famille f
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPays pp ON pp.IdFamille = f.IdFamille
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPaysProduitClient pppc ON pppc.IDProduitPays = pp.IDProduitPays
    	WHERE pppc.IDProduitClient = @idProduitClient
    	AND f.IdFamille NOT IN (
    		SELECT IdFamille 
    		FROM Test.dbo.Famille
    	)
    J'ai bien un décalage et il est dû au fait que j'ajoute la condition suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    AND f.IdFamille NOT IN (
    		SELECT IdFamille 
    		FROM Test.dbo.Famille
    	)
    Pour moi cette condition veut dire que je prends seulement les valeurs qui ne sont pas déjà enregistrées dans la table Famille.

    ou alors je me trompe ?
    Et dans ce cas, comment je m'assure que j'enregistre seulement les données dont j'ai besoins ?

  15. #15
    Membre du Club
    Inscrit en
    Février 2011
    Messages
    87
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 87
    Points : 47
    Points
    47
    Par défaut
    En fait, je crois que je viens de trouver la réponse ...
    Ma requête d'insertion était fausse :
    Dans ma première requête j'insère bien les 31 résultats, et lors de ma deuxième requête, pour insérer les Familles, je retourne 51 résultats à cause de ma condition qui était fausse.

    Ma requête me retourne ces 51 résultats car, elle me retourne bien les ProduitClient = 2 ET ceux qui ne sont pas dans la table Test (donc les 20 autres lignes)

    En fait je voulais faire une requête d'insertion qui insert QUE les données dont j'ai besoins !

    Du coup la requête devient, corrigez moi si je me trompe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    SELECT * FROM (
    SELECT DISTINCT(f.IdFamille), f.IDDonneeLibelle, f.Nom
    	FROM ServLie.BaseSource.dbo.Famille f
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPays pp ON pp.IdFamille = f.IdFamille
    	INNER JOIN ServLie.BaseSource.dbo.ProduitPaysProduitClient pppc ON pppc.IDProduitPays = pp.IDProduitPays
    	WHERE pppc.IDProduitClient = @idProduitClient
    ) as t 
    where t.IdFamille not in (
    SELECT IdFamille 
    FROM Test.dbo.Famille
    )

Discussions similaires

  1. Réponses: 1
    Dernier message: 07/11/2007, 18h51
  2. Réponses: 2
    Dernier message: 25/05/2006, 19h56
  3. liste chainée et insertion en fin ou debut
    Par bonjour69 dans le forum C
    Réponses: 7
    Dernier message: 21/12/2005, 20h50
  4. Insertion en début et non en fin de base ?
    Par sourcelab dans le forum Requêtes
    Réponses: 6
    Dernier message: 12/10/2005, 14h23
  5. INSERTION / tri ascendant ou descendant, ou mettre a la fin
    Par oravelon dans le forum Langage SQL
    Réponses: 5
    Dernier message: 05/08/2005, 11h15

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