web-dev-qa-db-fra.com

Comment modifier plusieurs colonnes à la fois dans SQL Server

J'ai besoin de ALTER les types de données de plusieurs colonnes d'une table.

Pour une seule colonne, cela fonctionne bien:

ALTER TABLE tblcommodityOHLC
ALTER COLUMN
    CC_CommodityContractID NUMERIC(18,0) 

Mais comment puis-je modifier plusieurs colonnes dans une déclaration? Ce qui suit ne fonctionne pas:

ALTER TABLE tblcommodityOHLC
ALTER COLUMN
    CC_CommodityContractID NUMERIC(18,0), 
    CM_CommodityID NUMERIC(18,0)
99
D.mahesh

Ce n'est pas possible. Vous devrez le faire un par un.

Vous pouvez créer une table temporaire avec vos colonnes modifiées, copier les données, supprimer votre table d'origine et renommer votre table temporaire en votre nom d'origine.

105
Neil Knight

Effectuer plusieurs actions ALTER COLUMN dans une seule instruction ALTER TABLE n'est pas Possible.

Voir la syntaxe ALTER TABLE ici:
http://msdn.Microsoft.com/en-US/library/ms190273.aspx

Vous pouvez faire plusieurs ADD ou plusieurs DROP COLUMN, mais un seul ALTER COLUMN.

17
Fernando Torres

La solution suivante ne consiste pas en une instruction unique permettant de modifier plusieurs colonnes, mais elle facilite la vie:

  1. Générez le script CREATE d'une table. 

  2. Remplacez CREATE TABLE par ALTER TABLE [TableName] ALTER COLUMN pour la première ligne 

  3. Supprimez les colonnes indésirables de la liste.

  4. Modifiez les types de données des colonnes comme vous le souhaitez.

  5. Effectuer un Rechercher et remplacer… comme suit:

    1. Trouver: NULL,
    2. Remplacer par: NULL; ALTER TABLE [TableName] ALTER COLUMN
    3. Hit Remplacer bouton.
  6. Exécutez le script.

J'espère que cela vous fera gagner beaucoup de temps :))

7
Pritam

Comme d’autres l’ont répondu, vous avez besoin de plusieurs instructions ALTER TABLE. Essayer:

ALTER TABLE tblcommodityOHLC alter column CC_CommodityContractID NUMERIC(18,0);
ALTER TABLE tblcommodityOHLC alter column CM_CommodityID NUMERIC(18,0);

etc.

5
Ray K.

Comme beaucoup d'autres l'ont dit, vous devrez utiliser plusieurs instructions ALTER COLUMN, une pour chaque colonne que vous souhaitez modifier.

Si vous souhaitez modifier toutes ou plusieurs colonnes de votre table sur le même type de données (par exemple, en développant un champ VARCHAR de 50 à 100 caractères), vous pouvez générer automatiquement toutes les instructions à l'aide de la requête ci-dessous. Cette technique est également utile si vous souhaitez remplacer le même caractère dans plusieurs champs (par exemple, en supprimant\t de toutes les colonnes).

SELECT
     TABLE_CATALOG
    ,TABLE_SCHEMA
    ,TABLE_NAME
    ,COLUMN_NAME
    ,'ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ALTER COLUMN ['+COLUMN_NAME+'] VARCHAR(300)' as 'code'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'your_table' AND TABLE_SCHEMA = 'your_schema'

Cela génère une instruction ALTER TABLE pour chaque colonne.

2
Evan

Si vous modifiez Management Studio et générez des scripts, il crée une nouvelle table et y insère les anciennes données avec les types de données modifiés. Voici un petit exemple modifiant les types de données de deux colonnes

/*
   12 August 201008:30:39
   User: 
   Server: CLPPRGRTEL01\TELSQLEXPRESS
   Database: Tracker_3
   Application: 
*/

/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.tblDiary
    DROP CONSTRAINT FK_tblDiary_tblDiary_events
GO
ALTER TABLE dbo.tblDiary_events SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_tblDiary
    (
    Diary_ID int NOT NULL IDENTITY (1, 1),
    Date date NOT NULL,
    Diary_event_type_ID int NOT NULL,
    Notes varchar(MAX) NULL,
    Expected_call_volumes real NULL,
    Expected_duration real NULL,
    Skill_affected smallint NULL
    )  ON T3_Data_2
     TEXTIMAGE_ON T3_Data_2
GO
ALTER TABLE dbo.Tmp_tblDiary SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_tblDiary ON
GO
IF EXISTS(SELECT * FROM dbo.tblDiary)
     EXEC('INSERT INTO dbo.Tmp_tblDiary (Diary_ID, Date, Diary_event_type_ID, Notes, Expected_call_volumes, Expected_duration, Skill_affected)
        SELECT Diary_ID, Date, Diary_event_type_ID, CONVERT(varchar(MAX), Notes), Expected_call_volumes, Expected_duration, CONVERT(smallint, Skill_affected) FROM dbo.tblDiary WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_tblDiary OFF
GO
DROP TABLE dbo.tblDiary
GO
EXECUTE sp_rename N'dbo.Tmp_tblDiary', N'tblDiary', 'OBJECT' 
GO
ALTER TABLE dbo.tblDiary ADD CONSTRAINT
    PK_tblDiary PRIMARY KEY NONCLUSTERED 
    (
    Diary_ID
    ) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2

GO
CREATE UNIQUE CLUSTERED INDEX tblDiary_ID ON dbo.tblDiary
    (
    Diary_ID
    ) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2
GO
CREATE NONCLUSTERED INDEX tblDiary_date ON dbo.tblDiary
    (
    Date
    ) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2
GO
ALTER TABLE dbo.tblDiary WITH NOCHECK ADD CONSTRAINT
    FK_tblDiary_tblDiary_events FOREIGN KEY
    (
    Diary_event_type_ID
    ) REFERENCES dbo.tblDiary_events
    (
    Diary_event_ID
    ) ON UPDATE  CASCADE 
     ON DELETE  CASCADE 

GO
COMMIT
1
Kevin Ross

Grâce à l'exemple de code d'Evan, j'ai pu le modifier davantage et le rendre plus spécifique aux tables commençant par des noms de colonne spécifiques ET gérer les spécificités des contraintes. J'ai exécuté ce code, puis copié la colonne [CODE] et je l'ai exécuté sans problème.

USE [Table_Name]
GO
SELECT
     TABLE_CATALOG
    ,TABLE_SCHEMA
    ,TABLE_NAME
    ,COLUMN_NAME
    ,DATA_TYPE
    ,'ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] DROP CONSTRAINT [DEFAULT_'+TABLE_NAME+'_'+COLUMN_NAME+']; 
ALTER TABLE  ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ALTER COLUMN ['+COLUMN_NAME+'] datetime2 (7) NOT NULL 
ALTER TABLE  ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ADD CONSTRAINT [DEFAULT_'+TABLE_NAME+'_'+COLUMN_NAME+'] DEFAULT (''3/6/2018 6:47:23 PM'') FOR ['+COLUMN_NAME+']; 
GO' AS '[CODE]'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'form_%' AND TABLE_SCHEMA = 'dbo'
 AND (COLUMN_NAME = 'FormInserted' OR COLUMN_NAME = 'FormUpdated')
 AND DATA_TYPE = 'datetime'
0
Brenden Kehren
select 'ALTER TABLE ' + OBJECT_NAME(o.object_id) + 
    ' ALTER COLUMN ' + c.name + ' DATETIME2 ' + 
    CASE WHEN c.is_nullable = 0 THEN 'NOT NULL' ELSE 'NULL' END
from sys.objects o
inner join sys.columns c on o.object_id = c.object_id
inner join sys.types t on c.system_type_id = t.system_type_id
where o.type='U'
and c.name = 'Timestamp'
and t.name = 'datetime'
order by OBJECT_NAME(o.object_id)

courtoisie de devio

0
Spyder

Si vous ne voulez pas tout écrire vous-même et changer toutes les colonnes dans le même type de données, cela peut vous faciliter la tâche:

select 'alter table tblcommodityOHLC alter column '+name+ 'NUMERIC(18,0);'
from syscolumns where id = object_id('tblcommodityOHLC ')

Vous pouvez copier et coller la sortie en tant que votre requête

0
Rishi