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 29/03/2011, 11h37   #1
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut creer Procédure sous sql server

Bonjour,
Dans le cadre de mon projet sur sqlserver, j'ai une table composé de 4
colonnes.
La première A colonne contient 4 valeurs:de 1 jusqu'à 4.
La deuxième colonne B contient 5 valeurs: de 1 jusqu'à' à 4 avec la valeur NULL.
La troisième colonne C contient 5 valeurs: de 1 jusqu'à' à 4 avec la valeur NULL.

Dans la 4eme colonne "combinaison", il faut créer une combinaison entre les colonnes A,B,C. exemple 1 ere valeur 1 c'est la combinaison 1, null,null
2 eme valeur c'est la combinaison 2,1,null.
J'ai pensé a créer une procédure qui met a jour la colonne combinaison.
voici l'idée:
For(i=1;i<4;i++)
For(j=1;i<5;j++)
For(k=1;i<5;k++)
et après update table set valeur++.
J'ai 2 problèmes:
1 La syntaxe:je n'arrive pas à créer cette procédure
2 valeur nul:Comment gérer les valeurs null alors que le compteur commence de 1
Merci de me proposer des solutions ou de corrections.
MERCI
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 12h43   #2
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 667
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 667
Points : 8 715
Points : 8 715
Bonjour,

Citation:
Dans la 4eme colonne "combinaison", il faut créer une combinaison entre les colonnes A,B,C. exemple 1 ere valeur 1 c'est la combinaison 1, null,null
2 eme valeur c'est la combinaison 2,1,null.
Ceci est faux parce que si vous stockez la suite de valeurs dans la 4e colonne, alors votre table ne respecte pas la première forme normale.
Celle-ci dicte que toute valeur stockée dans une colonne doit être atomique.

Si vous faites donc le contraire, vous partirez dans des requêtes tordues et longues et difficiles à écrire, en plus d'être bien évidemment contre-performantes.

Citation:
J'ai pensé a créer une procédure qui met a jour la colonne combinaison.
voici l'idée:
For(i=1;i<4;i++)
For(j=1;i<5;j++)
For(k=1;i<5;k++)
et après update table set valeur++.
Quand vous codez en SQL, et plus particulièrement en T-SQL, l'implémentation de SQL de Sybase et Microsoft (et d'autres ...), ne pensez plus comme vous coderiez dans un langage fonctionnel.
Dans un langage fonctionnel, vous écrivez comment vous voulez arriver à un résultat.
SQL est un langage déclaratif, donc vous lui dictez ce que vous voulez, et le moteur de bases de données le reste.

D'autre part SQL est un langage ensembliste, puisqu'il est fondé sur la théorie des ensembles.
En conséquence un bout de code qui serait traduit en SQL à partir de :

Code :
1
2
3
4
FOR(i=1;i<4;i++)
FOR(j=1;i<5;j++)
FOR(k=1;i<5;k++)
et après UPDATE TABLE SET valeur++.
Serait lent en plus d'être moche.

Citation:
La syntaxe:je n'arrive pas à créer cette procédure
C'est normal, ce n'est pas du SQL, ni du T-SQL

Citation:
valeur nul:Comment gérer les valeurs null alors que le compteur commence de 1
NULL n'est pas une valeur, c'est un marqueur qui indique l'absence de valeur.
D'aileurs si vous exécutez :

Code :
1
2
3
IF NULL = NULL
	SELECT 'OK'
ELSE SELECT 'KO'
Vous obtiendrez KO, ce qui prouve que NULL n'est pas une valeur.
Vous pouvez essayer tout autre opérateur arithmétique, vous obtiendrez toujours le même résultat.

Donc pour calculer toutes les combinaisons dont vous avez besoin, on peut créer la table suivante :

Code :
1
2
3
4
5
6
CREATE TABLE uneTableDeQuatreColonnes
(
	A tinyint
	, B tinyint
	, C tinyint
)
Et pour peupler la table comme suit :

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
;WITH
	A AS
	(
		SELECT	1 AS A
		UNION ALL SELECT 2
		UNION ALL SELECT 3
		UNION ALL SELECT 4
	)
	, B AS
	(
		SELECT	1 AS B
		UNION ALL SELECT 2
		UNION ALL SELECT 3
		UNION ALL SELECT 4
		UNION ALL SELECT NULL
	)
INSERT		dbo.uneTableDeQuatreColonnes
SELECT		A.A
		, B.B
		, C.B
FROM		A AS A
CROSS JOIN	B AS B
CROSS JOIN	B AS C
GO
Je crée ce que l'on appelle des expression de tables communes (deux, A et B), introduites par le mot clé WITH.
Pour chacune d'entre-elles, je les peuple avec les valeurs de votre énoncé.

Ensuite j’effectue un produit cartésien introduit par CROSS JOIN.
Donc si par exemple j'ai 4 valeurs dans A et 2 valeurs dans B, j'aurai 8 lignes.
Comme j'ai 4 valeurs dans A et 5 dans B, j'en ai 20.

Ensuite comme le jeu de valeurs de C est le même que B, je le réutilise et l'aliasse C.
J'avais 20 valeurs, que je remultiplie par 5, j'ai donc 100 combinaisons.

Si je fais :
Code :
1
2
SELECT	*
FROM	dbo.uneTableDeQuatreColonnes
J'ai bien 100 lignes.

Je vous conseille très vivement de commencer par apprendre ce qu'est SQL.
Pour cela le site de SQLPro contient tout ce qu'il faut

@++
__________________
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 29/03/2011, 13h14   #3
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Merci elsuket pour ton aide mais ma table est déjà créé donc la colonne A,B,C
sauf que j'ai ajouté la colonne combinaison pour affecter des valeurs .
Les valeurs existent déjà dans la colonne A,B,C mais elles sont pas stocké par ordre.
donc ca peut de la façon suivante
A B C
1 1 null
2 1 null
1 nul null
Et ainsi de suite.
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 13h57   #4
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut sqlserver

le but c'est d'avoir c'est d'avoir dans la table uneTableDeQuatreColonnes 4 colonnes

Valeurs stoké aléatoirement dans les colonnes A,B,C
et Un compteur dans combinaison:

A B C combinaison
1 null 4 1
1 1 null 2
4 nul 1 3

Etc
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 14h28   #5
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Un compteur ?

Quel serait le but de ce compteur et sur quel ordre se base-t-il ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 14h35   #6
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 667
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 667
Points : 8 715
Points : 8 715
Vous pouvez tronquer votre table pour la remplir avec la requête que je vous ai donné.

Si vous avez besoin d'avoir un "ordre" aléatoire dans votre table, il suffit de changer en écrivant :

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
;WITH
	A AS
	(
		SELECT	1 AS A
		UNION ALL SELECT 2
		UNION ALL SELECT 3
		UNION ALL SELECT 4
	)
	, B AS
	(
		SELECT	1 AS B
		UNION ALL SELECT 2
		UNION ALL SELECT 3
		UNION ALL SELECT 4
		UNION ALL SELECT NULL
	)
INSERT		dbo.uneTableDeQuatreColonnes
SELECT		A.A
		, B.B
		, C.B
		, ROW_NUMBER() OVER(ORDER BY NEWID()) AS compteur
FROM		A AS A
CROSS JOIN	B AS B
CROSS JOIN	B AS C
GO
@++
__________________
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 29/03/2011, 16h38   #7
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut sqlserver2008

merci elsuket encore pour ta réponse mais moi je ne peux pas remplir les colonnes A ,B et C.Il sont déjà rempli .dans le cadre de projet, je réalise la partie BI donc dans cette table site de montage, j'ai la colonne A qui est le siteMonteur ,déja rempli, colonne B site_approvisionnement déja rempli et table C fournisseur déja rempli.
Toutes ces colonnes je ne peux pas modifier.il faut que je créé une nouvelle colonne "combinaison "qui va affecter une combinaison a chaque tuple par exemple :
combinaison1 pour siteMonteur 1 ,site_approvisionnement NULL et fournisseur 2 et ainsi de suite.
Il faut avoir un id de combinaison pour chaque possibilité
MERCI
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 17h18   #8
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

Si je comprend bien, vous voulez juste attribuer un identifiant à chaque ligne de votre table, sans ordre particulier ?

vous pouvez faire ceci :
Code SQL :
1
2
3
4
5
6
 
DECLARE @Nb INT = 0
 
UPDATE MaTable
SET MaColonne = @Nb,
	@Nb += 1
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 17h50   #9
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut sql2008

merci,
je voudrai attribuer des identifiant pour 100 lignes parce que je peux avoir 100 possibilités entre la colonne siteMonteur,site_approvisionnement et fournisseur .
Donc pour chaque combinaison possible, il faut affecter1 identifiant.
Merci
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 18h06   #10
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573


Vous voulez dire que dans votre table, vous pouvez avoir plusieurs fois la même combinaison et que dans ce cas, elles devront avoir le même identifiant ?
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 18h13   #11
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut sqlserver2008

oui,exactement
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 18h20   #12
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
est-ce que ceci repond au besoin ?

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
 
 
UPDATE MaTable
SET id = Nb
FROM (
	SELECT A,B,C, DENSE_RANK() OVER (ORDER BY A,B,C) AS Nb
	FROM MaTable
	) T
WHERE MaTable.A = T.A 
	AND (MaTable.B = T.B OR COALESCE(MaTable.B, T.B) IS NULL)
	AND (MaTable.C = T.C OR COALESCE(MaTable.C, T.C) IS NULL)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2011, 18h44   #13
Invité de passage
 
Inscription : février 2011
Messages : 32
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 32
Points : 1
Points : 1
Par défaut sqlserver2008

merci aieeeuuuu
C'est exactement ce que je voulais. super !!!
Par contre est ce que vous pouvez m'expliquer ce que vous avez fait?
surtout les 2 commandes COALESCE et DENSE_RANK()
Je n'ai pas bien compris ce qu'ils font.
Merci
toga222 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2011, 10h43   #14
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
bonjour,

DENSE_RANK ordonne les différentes combinaisons de A,B et C, et donne, pour chacune d'elle, son rang. Cela permet de générer l'identifiant pour chaque combinaison.

vous pouvez exécuter directement la sous requete
Code SQL :
1
2
3
 
SELECT A,B,C, DENSE_RANK() OVER (ORDER BY A,B,C) AS Nb
FROM MaTable
pour voir le resultat intermediaire

Reste à mettre à jour la table avec ces données !
Pour cela, je fais un UPDATE en utilisant la pseudo table (requête ci-dessous), et je récupere l'ID (fournit par DENSE_RANK) en cherchant dans la pseudo table la ligne qui presente la même combinaison, soit basiquement
Citation:
Table.A = pseudoTable.A
ET
Table.B = pseudoTable.B
ET
Table.C = pseudoTable.C
Sauf que vos colonnes B et C peuvent être à NULL, et dans ce cas, si Table.B est NULL et pseudoTable.B et NULL également, la condition
Table.B = pseudoTable.B n'est pas vérifiée car NULL n'est pas égal à NULL

Il faut donc vérifier si Table.B = pseudoTable.B OU si les deux sont NULL

COALESCE retourne la valeur du premier paramètre non null. Si (et seulement si) tous les parametres sont NULL(le cas qui nous interesse ici), cette fonction renvoi NULL

On aurait aussi pu écrire (ce qui serait équivalent):
Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
WHERE MaTable.A = T.A 
	AND (
		MaTable.B = T.B 
		OR (
			MaTable.B IS NULL
			AND
			T.B IS NULL
		)
	)
	AND (
		MaTable.C = T.C 
		OR (
			MaTable.C IS NULL
			AND
			T.C IS NULL
		)
	)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h39.


 
 
 
 
Partenaires

Hébergement Web