Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
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 05/07/2011, 14h26   #1
En attente de confirmation mail
 
Inscription : novembre 2002
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2002
Messages : 19
Points : 4
Points : 4
Envoyer un message via ICQ à bambino
Par défaut Supprimer toutes les colonnes d'une table à l'exception de certaines

Bonjour,

Ce message fait un peu suite a mon message précédent supprimer plusieurs colonnes en une seule requete.
J'avais simplifié mon problème de façon à le rendre plus clair avant de le poster sur le forum mais finalement du coup je suis passé a coté de mon vrai problème.


Voici mon problème, j'ai une table dans laquelle j'ai des colonnes a conserver (je connais le nom de celles-ci) et je dois supprimer toutes les autres (sans en connaitre leur nom)

Par exemple j'ai une table "MaTable" qui contient les champs suivants : col1,col2,col3,col4,col5,col6,col7

Je sais juste que je doit supprimer tous les champs de la table à l'exception de col1,col3 et col4. Le tout bien sur en ignorant que les autres colonnes s'appellent col2,col5,col6,col7

J'ai donc une requete pour retrouver le nom de toutes les colonnes que je dois supprimer :
Code :
1
2
3
4
5
6
SELECT syscolumns.Name
  FROM syscolumns
       INNER JOIN sysobjects
         ON syscolumns.id = sysobjects.id
 WHERE sysobjects.name = 'MaTable'
   AND syscolumns.Name NOT IN ('col1', 'col3', 'col4')
Résultat : col2,col5,col6,col7

Et je voudrais faire un drop de ces colonnes mais la requete échoue lorsque je fait :
Code :
1
2
3
4
5
6
7
ALTER TABLE [MaTable] DROP COLUMN
SELECT syscolumns.Name
  FROM syscolumns
       INNER JOIN sysobjects
         ON syscolumns.id = sysobjects.id
 WHERE sysobjects.name = 'MaTable'
   AND syscolumns.Name NOT IN ('col1', 'col3', 'col4')
Résultat : Syntaxe incorrecte vers le mot clé 'SELECT'.

(j'ai la même erreur si j'encapsule la sous-requête entre parenthèses)

Existe-t-il une façon de répondre a mon besoin en une seule requete sans devoir passer par un curseur qui ferai une boucle de DROP COLUMN ?

Edit : bon je ne suis pas borné je ne souhaite pas absolument avoir une seule requete pour faire cela mais j'aimerai au moins pouvoir me passer de la dizaine de lignes d'instructions qu'impliquerai l'utilisation d'un curseur.

Merci d'avance.
bambino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2011, 14h57   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 684
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 684
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
En une seule exécution, non pas moyen de le faire en SQL "pur".
Par contre, vous pouvez générer vos ordres SQL et exécuter le résultat :
Code :
1
2
3
4
5
6
SELECT 'ALTER TABLE ' + so.Name + ' DROP COLUMN ' + sc.Name AS req
  FROM syscolumns AS sc
       INNER JOIN sysobjects AS so
         ON so.id = sc.id
 WHERE so.Name = 'MaTable'
   AND sc.Name NOT IN ('col1', 'col3', 'col4')
Par contre, confirmez-nous qu'il s'agit bien d'une opération exceptionnelle : vous ne faites pas des ADD / DROP column à tout bout de champ ?
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2011, 15h40   #3
En attente de confirmation mail
 
Inscription : novembre 2002
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2002
Messages : 19
Points : 4
Points : 4
Envoyer un message via ICQ à bambino
Merci pour votre réponse,
Oui il s'agit d'une opération a caractère exceptionnel.

Par contre sachant que tout ceci doit etre executé dans un script T-SQL je me retrouve donc obligé de passer par un curseur pour executer les ordres sql que m'a généré la requete précédente (celle que vous avez indiqué dans votre réponse), ce que je voulais éviter mais bon tant pis si j'ai pas le choix je vais procéder comme ça alors.

Encore merci !

(Et merci aussi pour la remise en forme de mon précédent message, en effet j'avais pas fait un post très propre)
bambino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2011, 15h51   #4
En attente de confirmation mail
 
Inscription : novembre 2002
Messages : 19
Détails du profil
Informations forums :
Inscription : novembre 2002
Messages : 19
Points : 4
Points : 4
Envoyer un message via ICQ à bambino
Si jamais ça peut servir ou intéresser quelqu'un voici le script complet:

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
 
-- Supprimer toutes les colonnes d'une table à l'exception de certaines dont on connait les noms
DECLARE @NOM_TABLE AS VARCHAR(50)
SET @NOM_TABLE = 'MATABLE'
IF EXISTS ( SELECT name FROM sysobjects WHERE name = @NOM_TABLE AND type = 'U')
BEGIN
	DECLARE @SQL AS VARCHAR(MAX)
	-- Déclaration du Curseur de sélection
	DECLARE TEMPCURSEUR CURSOR 
	FOR SELECT 'ALTER TABLE ['+ @NOM_TABLE +'] DROP COLUMN '+ syscolumns.Name AS SQLCMD
			FROM syscolumns INNER JOIN sysobjects ON syscolumns.id = sysobjects.id 
			WHERE sysobjects.name=@NOM_TABLE
			AND syscolumns.Name NOT IN ('col1','col3','col4') --ici col1,col3,col4 représentent les seules colonnes que l'on souhaite conserver de la table
	-- Déclaration du Curseur sur la liste des colonnes a supprimer
	OPEN TEMPCURSEUR 
	FETCH NEXT FROM TEMPCURSEUR INTO @SQL
	WHILE (@@FETCH_STATUS >= 0)
		BEGIN 
			EXECUTE (@SQL)
			IF @@ERROR != 0 
				GOTO ROLLBACK_ON_ERROR
			FETCH NEXT FROM TEMPCURSEUR INTO @SQL 
		END
	-- Fermeture du Curseur 
	CLOSE TEMPCURSEUR 
	-- Libération de la mémoire prise par le Curseur 
	DEALLOCATE TEMPCURSEUR
END
COMMIT TRANSACTION 
RETURN 
ROLLBACK_ON_ERROR:
   ROLLBACK TRANSACTION
bambino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/07/2011, 16h18   #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
Vous pouviez effectivement vous passer de curseur, et lancer un seul ordre DDL par table :

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
 
--suppression de toutes les colonnes de la table T, sauf col2 et col4
DECLARE @SQL NVARCHAR(MAX)
 
SELECT @SQL = 
	CASE  
		WHEN @SQL IS NULL THEN '' 
		ELSE @SQL + ',' 
	END 
	+ COLUMN_NAME
FROM  INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'T'
	AND COLUMN_NAME NOT IN ('col2', 'col4')
 
SET @SQL = 'ALTER TABLE T DROP COLUMN ' + @SQL
 
EXEC sp_executesql @SQL
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 03h10.


 
 
 
 
Partenaires

Hébergement Web