SQL Server에서 한 번에 여러 열을 변경하는 방법


143

ALTER테이블에 여러 열의 데이터 유형이 필요 합니다.

단일 열의 경우 다음이 정상적으로 작동합니다.

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

그러나 한 문장에서 여러 열을 어떻게 변경합니까? 다음은 작동하지 않습니다.

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

1
한 번에 수행 할 때 인식되는 이점은 무엇입니까?
언젠가

5
@onedaywhen-SQL Server는 새로운 데이터 형식에 대해 필요한 유효성 검사를 수행하거나 변경된 형식의 열을 새 형식으로 작성하기 위해 테이블을 한 번 통과시킵니다.
Martin Smith

1
그렇다면 큰 장점은 없습니다!
1

4
반대로. 큰 테이블의 여러 열에 대해 24 시간 대신 2 시간 내에 변경 실행을하는 것이 큰 이점입니다.
Norbert Kardos

답변:


135

이건 불가능 해. 이 작업을 하나씩 수행해야합니다.

수정 된 열이있는 임시 테이블을 작성하고, 데이터를 복사하고, 원래 테이블을 삭제하고 임시 테이블의 이름을 원래 이름으로 바꿀 수 있습니다.


5
+1, You will need to do this one by one.그래서 가장 중요한 것은 여러 ALTER TABLE ALTER COLUMN명령을 사용하는 것 입니까?
KM.

6
@ KM 하나의 문제는 큰 테이블을 변경하는 것입니다. 각 문은 새로운 스캔을 의미하지만 여러 열을 변경할 수 있으면 모든 변경이 훨씬
빨라질

SSMS 도구는 일반적으로 자신의 스크립트를 생성처럼 @erikkallen, 다음을 수행하십시오, 새 테이블의 이름을 변경 한 후, 등, 새로운 테이블과 복제 FKS 및 인덱스를 생성 원래 테이블을 드롭
KM을.

테이블을 삭제하고 다시 만드는 것은 매우 집중적 인 작업입니다. SSMS에서는 기본적으로 비활성화되어 있으며 아마도 그럴만한 이유가 있습니다.
jocull

"Each statement means a new scan": 반드시 @erikkallen 일 필요는 없습니다. 경우에 따라 ALTER 열은 단순한 메타 데이터 변경입니다. 내일 강의에 참여하여 " SQL Internals - Physical Table Structure under the hood, and implementation on real case scenarios"에 관한 실습을 모두 볼 수 있습니다 :-)
Ronen Ariely

26

ALTER COLUMN단일 ALTER TABLE명령문 내에서 여러 조치를 수행 할 수 없습니다.

여기ALTER TABLE구문을 참조 하십시오

여러 개 ADD또는 여러 개를 수행 할 수 DROP COLUMN있지만 단 하나만 수행 할 수 있습니다 ALTER COLUMN.


17

다른 사람들이 대답했듯이 여러 ALTER TABLE진술 이 필요 합니다.
다음을 시도하십시오.

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

12

다음 솔루션은 여러 열을 변경하는 단일 명령문이 아니지만 간단하게 수명을 연장합니다.

  1. 테이블의 CREATE스크립트를 생성하십시오 .

  2. 교체 CREATE TABLE와 함께 ALTER TABLE [TableName] ALTER COLUMN첫 번째 줄에

  3. 목록에서 원하지 않는 열을 제거하십시오.

  4. 원하는대로 열 데이터 유형을 변경하십시오.

  5. 다음과 같이 찾기 및 바꾸기… 를 수행하십시오 .

    1. 찾기 : NULL,
    2. 다음으로 교체하십시오. NULL; ALTER TABLE [TableName] ALTER COLUMN
    3. 히트 바꾸기 버튼을 클릭합니다.
  6. 스크립트를 실행하십시오.

많은 시간을 절약 할 수 있기를 바랍니다 :))


6

다른 많은 사람들이 말했듯 ALTER COLUMN이 수정하려는 각 열마다 하나씩 여러 문 을 사용해야 합니다.

VARCHAR 필드를 50에서 100 자로 확장하는 것과 같이 테이블의 전체 또는 여러 열을 동일한 데이터 유형으로 수정하려는 경우 아래 쿼리를 사용하여 모든 명령문을 자동으로 생성 할 수 있습니다. 이 기술은 여러 필드에서 동일한 문자를 바꾸려는 경우에도 유용합니다 (예 : 모든 열에서 \ t 제거).

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'

그러면 ALTER TABLE각 열에 대한 설명 이 생성됩니다 .


1

Management Studio에서 변경을 수행하고 스크립트를 생성하는 경우 새 테이블을 작성하고 이전 데이터를 변경된 데이터 유형이있는 테이블에 삽입합니다. 다음은 두 열의 데이터 유형을 변경하는 작은 예입니다.

/*
   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

전체를 직접 작성하고 모든 열을 동일한 데이터 유형으로 변경하지 않으려면 더 쉬울 수 있습니다.

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

출력을 쿼리로 복사하여 붙여 넣을 수 있습니다


0
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)

devio의 의례


0

Evan의 코드 샘플 덕분에 더 수정하고 특정 열 이름으로 시작하고 제약 조건에 대한 세부 사항을 처리하는 테이블에 더 구체적으로 가져올 수있었습니다. 해당 코드를 실행 한 다음 [CODE] 열을 복사하여 문제없이 실행했습니다.

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
-- create temp table 
CREATE TABLE temp_table_alter
(
column_name varchar(255)    
);

-- insert those coulmns in temp table for which we nee to alter size of columns 
INSERT INTO temp_table_alter (column_name) VALUES ('colm1');
INSERT INTO temp_table_alter (column_name) VALUES ('colm2');
INSERT INTO temp_table_alter (column_name) VALUES ('colm3');
INSERT INTO temp_table_alter (column_name) VALUES ('colm4');

DECLARE @col_name_var varchar(255);
DECLARE alter_table_cursor CURSOR FOR
select column_name from temp_table_alter ;

OPEN alter_table_cursor
FETCH NEXT FROM alter_table_cursor INTO @col_name_var
WHILE @@FETCH_STATUS = 0
 BEGIN

 PRINT('ALTER COLUMN ' + @col_name_var);
 EXEC ('ALTER TABLE Original-table  ALTER COLUMN ['+ @col_name_var + '] DECIMAL(11,2);')

 FETCH NEXT FROM alter_table_cursor INTO @col_name_var
 END

CLOSE alter_table_cursor
DEALLOCATE alter_table_cursor

-- at the end drop temp table
drop table temp_table_alter;

좋은 해결책이 아닙니다. 커서와 루프는 모든 비용으로 피해야합니다 !!!
Ray K.

1
사실이 아니야, 레이 커서와 루프는 특정 DDL 작업 및 기타 필수 RBR 작업에 적합합니다.
Jeff Moden

-3

다음과 같이 단일 쿼리에서 여러 열을 변경할 수 있습니다.

ALTER TABLE `tblcommodityOHLC`
    CHANGE COLUMN `updated_on` `updated_on` DATETIME NULL DEFAULT NULL AFTER `updated_by`,
    CHANGE COLUMN `delivery_datetime` `delivery_datetime` DATETIME NULL DEFAULT CURRENT_TIMESTAMP AFTER `delivery_status`;

쿼리를 쉼표로 구분하여 제공하십시오.


4
나는 이것이 MySql이라고 생각합니까? 질문은 SQL Server에 대한 것이며 SQL 서버에서는 작동하지 않습니다.
Tjipke

-4

ALTER COLUMN괄호 안에 문장을 넣으면 작동합니다.

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

-4

귀하의 질문을 올바르게 이해했다면 아래 언급 된 쿼리를 사용하여 테이블에 여러 열을 추가 할 수 있습니다.

질문:

Alter table tablename add (column1 dataype, column2 datatype);

4
OP는 ADD가 아닌 ALTER 열에 대해 물었습니다.
DR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.