Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/10/2011, 17h39   #1
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 :
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
 
...
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/10/2011, 18h46   #2
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
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.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 08h52   #3
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 ...
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 12h58   #4
Rédacteur/Modérateur

 
Avatar de WOLO Laurent
 
Homme Laurent WOLO
Architecte de base de données
Inscription : mars 2003
Messages : 2 696
Détails du profil
Informations personnelles :
Nom : Homme Laurent WOLO
Âge : 35
Localisation : Congo-Brazzaville

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

Informations forums :
Inscription : mars 2003
Messages : 2 696
Points : 3 917
Points : 3 917
Envoyer un message via Yahoo à WOLO Laurent
Est ce que tu peux nous donner la définition des tables ainsi le code que tu exécutes et qui poserait problème ?
__________________

Découvrez la FAQ de MS SQL Server.
La chance accorde ses faveurs aux esprits avertis !
WOLO Laurent est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 15h17   #5
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 :
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 :
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 :
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
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 16h11   #6
Rédacteur/Modérateur

 
Avatar de WOLO Laurent
 
Homme Laurent WOLO
Architecte de base de données
Inscription : mars 2003
Messages : 2 696
Détails du profil
Informations personnelles :
Nom : Homme Laurent WOLO
Âge : 35
Localisation : Congo-Brazzaville

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

Informations forums :
Inscription : mars 2003
Messages : 2 696
Points : 3 917
Points : 3 917
Envoyer un message via Yahoo à WOLO Laurent
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.
__________________

Découvrez la FAQ de MS SQL Server.
La chance accorde ses faveurs aux esprits avertis !
WOLO Laurent est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 16h25   #7
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 17h02   #8
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
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 :
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
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 17h06   #9
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 17h19   #10
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
Je viens d'essayer la requête récursive ... aucun résultats ...

*PAN*
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 17h31   #11
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 ...
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/10/2011, 17h33   #12
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
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 :
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 ?

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/10/2011, 09h18   #13
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
J'ai lancé la requête après mon script d'insertion et donc après plantage !

J'ai bien des réponses ...

Code :
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 !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/10/2011, 13h47   #14
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 :
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 :
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 :
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 ?
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/10/2011, 13h58   #15
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
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 :
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
)
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h15.


 
 
 
 
Partenaires

Hébergement Web