SQL서버 SQL강좌: 5-4. 테이블 수정

코난(김대우) 2023.08.18 16:33 Views : 88 Upvote:1

안녕하세요. SQLER의 코난 김대우입니다. 
이번 강좌에서는, 5-4. 테이블 수정을 진행 하겠습니다.


SQLER에서 진행되는, 챗GPT와 함께 배우는 SQL Server 강좌 목록

 

이번에 진행할 강좌는 테이블 수정입니다.

 

 

 

TL;DR

테이블은 ALTER TABLE 구문을 사용하여 컬럼을 추가하거나 수정할 수 있습니다. 기존 데이터가 있는 경우 주의하여 NULL 설정 및 컬럼 크기 변경을 처리해야 합니다.



지난 테이블 생성 강좌는 길고 생소한 내용이 많아 어려웠을 거예요. 테이블 생성 강좌를 잘 마치셨으니, 수정 강좌는 훨씬 쉽습니다. 테이블 생성과 거의 같은 작업이기 때문입니다. 


이전 강좌에서 진행한 테이블 생성 구문 - CREATE TABLE구문 기억하시죠? 
테이블 수정 구문은 ALTER TABLE 구문입니다. SQL Server에서 주요 개체 생성은 CREATE, 수정은 대부분 ALTER 구문으로 처리합니다. 이번에도 SSMS는 짧게 진행하고, 다음 SQL 쿼리로 테이블 수정을 진행하겠습니다.


지난 강좌에서 생성한 member_test3 테이블을 SSMS에서 열어주세요. 혹시 테이블을 지웠다면 아래 SQL 쿼리로 생성하고 1개 데이터를 넣습니다.

 

-- 만약 테이블이 존재하면 삭제
IF OBJECT_ID(N'dbo.members_test3', N'U') IS NOT NULL  
   DROP TABLE dbo.members_test3;  
GO

-- 테이블 수정에서 사용
CREATE TABLE members_test3 (
  member_num INT PRIMARY KEY IDENTITY(1, 1),
  member_name NVARCHAR(10),
  email NVARCHAR(15) NOT NULL,
  register_date datetime DEFAULT GETDATE()
);
GO

-- 예제 데이터 1개 삽입
INSERT INTO members_test3(member_name, email, register_date)
VALUES(N'김대우', N'kdw@example.com', '2023-07-09');
GO

 


SSMS에서 테이블 디자인

64-1-테이블디자인.png

이미지 - 테이블 디자인

 

SSMS에서 테이블 - member_test3 테이블을 선택하고 “디자인”을 실행하면 지난 강좌의 생성과 유사한 테이블 디자인 화면이 실행됩니다.

 

64-2-컬럼추가.png

이미지 - 컬럼 추가


이렇게 birthday와 hobby 컬럼을 추가합니다. 이때 NULL 허용에 체크해야 합니다. 컬럼 추가 후 저장 버튼을 눌러서 저장하세요.

USE AdventureWorks;
GO

-- 컬럼 추가 후 예제 데이터 1개 삽입
INSERT INTO members_test3(member_name, email, register_date, birthday, hobby)
VALUES(N'박서준', N'psj@example.com', '2023-07-20', '2000-01-01', N'독서');
GO

SELECT * FROM members_test3;
GO

 

이렇게 간략히, SSMS에서 테이블에 컬럼을 추가할 수 있습니다. 


이런 작업도 가능합니다. - name 컬럼이 현재 nvarchar(10)로 되어 있는데 물론 늘릴 수도 있겠지요? NULL가능 컬럼을 NOT NULL으로 바꿀 수도 있습니다. 


하지만, 현재 데이터가 존재하기 때문에 현재 테이블의 값보다 작게 컬럼의 크기를 줄이거나, NULL 값이 이미 테이블에 존재하는데 NOT NULL로 변경하면 오류가 발생하니 주의합니다.

 

 

SQL 쿼리로 테이블 수정

다음은 SQL 쿼리로 수행합니다. 역시나 먼저 구문 정보를 확인하겠습니다. 전체적으로 이런 구조라는 것만 짧게 보고 지나가셔도 됩니다.

ALTER TABLE { database_name.schema_name.table_name | schema_name.table_name | table_name }
{
    ALTER COLUMN column_name
    {
        [ type_schema_name. ] type_name
            [ (
                {
                   precision [ , scale ]
                 | max
                 | xml_schema_collection
                }
            ) ]
        [ COLLATE collation_name ]
        [ NULL | NOT NULL ] [ SPARSE ]
      | { ADD | DROP }
          { ROWGUIDCOL | PERSISTED | NOT FOR REPLICATION | SPARSE | HIDDEN }
      | { ADD | DROP } MASKED [ WITH ( FUNCTION = ' mask_function ') ]
    }
    [ WITH ( ONLINE = ON | OFF ) ]
    | [ WITH { CHECK | NOCHECK } ]
  
    | ADD
    {
        <column_definition>
      | <computed_column_definition>
      | <table_constraint>
      | <column_set_definition>
    } [ ,...n ]
      | [ system_start_time_column_name datetime2 GENERATED ALWAYS AS ROW START
                [ HIDDEN ] [ NOT NULL ] [ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES] ,
                system_end_time_column_name datetime2 GENERATED ALWAYS AS ROW END
                   [ HIDDEN ] [ NOT NULL ][ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES] ,
                start_transaction_id_column_name bigint GENERATED ALWAYS AS TRANSACTION_ID START
                   [ HIDDEN ] NOT NULL [ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES],
                  end_transaction_id_column_name bigint GENERATED ALWAYS AS TRANSACTION_ID END
                   [ HIDDEN ] NULL [ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES],
                  start_sequence_number_column_name bigint GENERATED ALWAYS AS SEQUENCE_NUMBER START
                   [ HIDDEN ] NOT NULL [ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES],
                  end_sequence_number_column_name bigint GENERATED ALWAYS AS SEQUENCE_NUMBER END
                   [ HIDDEN ] NULL [ CONSTRAINT constraint_name ]
            DEFAULT constant_expression [WITH VALUES]
        ]
       PERIOD FOR SYSTEM_TIME ( system_start_time_column_name, system_end_time_column_name )
    | DROP
     [ {
         [ CONSTRAINT ][ IF EXISTS ]
         {
              constraint_name
              [ WITH
               ( <drop_clustered_constraint_option> [ ,...n ] )
              ]
          } [ ,...n ]
          | COLUMN [ IF EXISTS ]
          {
              column_name
          } [ ,...n ]
          | PERIOD FOR SYSTEM_TIME
     } [ ,...n ]
    | [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT
        { ALL | constraint_name [ ,...n ] }
  
    | { ENABLE | DISABLE } TRIGGER
        { ALL | trigger_name [ ,...n ] }
  
    | { ENABLE | DISABLE } CHANGE_TRACKING
        [ WITH ( TRACK_COLUMNS_UPDATED = { ON | OFF } ) ]
  
    | SWITCH [ PARTITION source_partition_number_expression ]
        TO target_table
        [ PARTITION target_partition_number_expression ]
        [ WITH ( <low_priority_lock_wait> ) ]

    | SET
        (
            [ FILESTREAM_ON =
                { partition_scheme_name | filegroup | "default" | "NULL" } ]
            | SYSTEM_VERSIONING =
                  {
                    OFF
                  | ON
                      [ ( HISTORY_TABLE = schema_name . history_table_name
                          [, DATA_CONSISTENCY_CHECK = { ON | OFF } ]
                          [, HISTORY_RETENTION_PERIOD =
                          {
                              INFINITE | number {DAY | DAYS | WEEK | WEEKS
                  | MONTH | MONTHS | YEAR | YEARS }
                          }
                          ]
                        )
                      ]
                  }
            | DATA_DELETION =  
                {
                      OFF 
                    | ON  
                        [(  [ FILTER_COLUMN = column_name ]   
                            [, RETENTION_PERIOD = { INFINITE | number {DAY | DAYS | WEEK | WEEKS 
                                    | MONTH | MONTHS | YEAR | YEARS }}]   
                        )]
                    }
    | REBUILD
      [ [PARTITION = ALL]
        [ WITH ( <rebuild_option> [ ,...n ] ) ]
      | [ PARTITION = partition_number
           [ WITH ( <single_partition_rebuild_option> [ ,...n ] ) ]
        ]
      ]
  
    | <table_option>
    | <filetable_option>
    | <stretch_configuration>
}
[ ; ]


테이블의 수정도 ALTER TABLE 구문입니다. SQLER 강좌가 늘 그렇죠? SQL 쿼리 예제를 통해 살펴보겠습니다.

 

테이블 컬럼 수정

members_test3 테이블 컬럼을 또 변경해 보겠습니다. member_name이 현재 nvarchar(10)인데, nvarchar(20)으로 변경합니다.

-- members_test3 테이블의 member_name 컬럼을 nvarchar(20)으로 변경
ALTER TABLE members_test3 ALTER COLUMN member_name NVARCHAR(20) NOT NULL;
GO

-- members_test3 테이블의 변경을 확인합니다.
sp_help members_test3;
GO

 

이렇게 sp_help로 변경을 확인 가능합니다.

다음은 member_name 컬럼을 NULL 가능 컬럼으로 변경합니다. 

-- members_test3 테이블의 member_name 컬럼을 NULL 가능 컬럼으로 변경
ALTER TABLE members_test3 ALTER COLUMN member_name NVARCHAR(20) NULL;
GO

-- members_test3 테이블의 변경을 확인합니다.
sp_help members_test3;
GO

 

확인은 “sp_help 테이블명”으로 하셔도 되며, SSMS의 테이블 디자인에서도 확인 가능합니다. 참고로 SQL 쿼리로 테이블을 수정 후 SSMS에서 확인하려면, 새로고침 해야만 변경사항이 적용되니 주의하세요.

 

테이블 컬럼 추가

다음은 테이블에 컬럼을 추가하는 SQL 구문입니다. ADD 키워드를 이용합니다.
아래 SQL 구문은 is_student 컬럼을 테이블에 추가합니다. NOT NULL로 추가를 시도해 보겠습니다.

-- 새로운 컬럼 is_student를 추가
ALTER TABLE members_test3 ADD is_student bit NOT NULL;
GO

메시지 4901, 수준 16, 상태 1, 줄 32
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column, or alternatively if none of the previous conditions are satisfied the table must be empty to allow addition of this column. Column 'is_student' cannot be added to non-empty table 'members_test3' because it does not satisfy these conditions.


항상 오류 메시지를 상세히 봐 두세요. 오류가 발생한 이유는 무엇입니까?

 

- 기존 테이블에 is_student 값이 없음
- 새 컬럼 is_student를 추가하면서 NOT NULL로 선언
- 기존 테이블 로우는 NULL 값이 되기 때문에 NOT NULL로 선언 불가 오류 발생

 

어떻게 해결해야 할까요?


해당 컬럼을 NOT NULL로 선언하고 추가해야 한다면, 기존 테이블 로우들의 is_student 값을 특정 값으로 추가해 줘야 합니다. NOT NULL로 해야만 한다면, 일반적으로 아래 절차를 고려하세요.


- NULL 가능 컬럼으로 추가
- 기존 테이블 로우의 is_student 값을 추가해 채움
- 컬럼을 NOT NULL로 변경


절차를 취합니다. 더 좋은 방법은 항상 테이블 디자인 시 ‘DEFAULT(기본값)”을 고려해 NULL 값을 받지 않게 설계하는 방법입니다. 5-3. 테이블 생성 강좌의 NULL 컬럼을 참조하세요.

 

-- is_student 컬럼을 NULL 가능으로 추가
ALTER TABLE members_test3 ADD is_student bit NULL;
GO

-- members_test3 테이블의 is_student 값을 채움
UPDATE members_test3 SET is_student = 0
WHERE is_student IS NULL;  -- NULL 인 값을 모두 0으로 수정
GO

-- members_test3 테이블의 is_student 컬럼을 NOT NULL 컬럼으로 변경
ALTER TABLE members_test3 ALTER COLUMN is_student NVARCHAR(20) NOT NULL;
GO

이렇게 가능합니다.

 

테이블 컬럼 삭제

컬럼 삭제 SQL 구문입니다. SSMS 테이블 디자인에서 컬럼을 선택하고 삭제하면 됩니다.

 

64-3-컬럼삭제.png

이미지 - 테이블 컬럼 삭제


SSMS 테이블 디자인 화면에서는 작업 후 반드시 저장을 눌러야 적용이 되니 주의하세요.

 

다음은, SQL 쿼리로 컬럼을 삭제하겠습니다. 이번에는 birthday 컬럼을 삭제합니다.

-- birthday 컬럼 삭제
ALTER TABLE members_test3 DROP COLUMN birthday;
GO

EXEC sp_help members_test3;
GO

 

SSMS의 테이블 디자인 처리 방식과 SQL 쿼리 방식을 모두 살펴보았습니다. 가능한 SQL 쿼리를 이용하실 것을 권장해 드려요. 코드로 작성되어 Github과 같은 원격 코드 저장소에 올려놓고 재사용 가능하며, 직관적이기 때문입니다. 테이블 구조를 변경했다면, 테이블 생성 구문을 스크립트로 받아서 코드 저장소에 저장해 두는 것도 좋습니다.


☑️ 챗GPT 활용: Github에 대해서 알려줘

 

 

테이블 삭제

마지막으로 테이블 삭제입니다. 이미 쿼리로 몇 번 수행했습니다. SSMS에서는 개체 탐색기에서 이렇게 삭제하면 됩니다.

64-4-테이블삭제.png

이미지 - 테이블 삭제

 

SQL 쿼리는 DROP TABLE구문을 사용합니다.

-- 테이블 삭제
DROP TABLE members_test3;
GO

 

어렵게만 보였던 테이블 생성과 수정, 삭제까지 진행했습니다. 나머지 테이블 작업은 대부분 테이블을 생성하면서 기본 키(PRIMARY KEY)를 잡거나 제약을 설정하는 것이기 때문에, 테이블 생성이나 수정처럼 어렵지 않습니다. 다음 강좌에서 차근차근 같이 진행하시죠.
 

 

SQL 강좌 책 구매

강좌가 도움이 되셨다면, 책으로 구매 가능합니다. 책 판매 수익금은 전액 코딩 교육 사회공헌 활동에 기부되며, 아래 링크에서 구매하시면 더 많은 금액이 기부됩니다. 

 

책구매 링크: 챗GPT와 함께하는 마이크로소프트 SQL Server 2022 

책구매링크.png

No. Subject Author Date Views
Notice SQL강좌: 챗GPT와 함께 배우는 SQL Server 무료 강좌 목차와 소개 (2023년 9월 업데이트) 코난(김대우) 2023.08.18 33952
Notice Python 무료 강좌 - 기초, 중급, 머신러닝(2023년 6월 업데이트) 코난(김대우) 2021.01.01 17162
2254 SQL강좌: 6-2. 데이터 무결성 - 테이블 컬럼과 NULL 제약 코난(김대우) 2023.08.18 58
2253 SQL강좌: 6-1. 데이터 무결성 - 데이터 무결성 이해 file 코난(김대우) 2023.08.18 84
» SQL강좌: 5-4. 테이블 수정 file 코난(김대우) 2023.08.18 88
2251 SQL강좌: 5-3. 테이블 생성 file 코난(김대우) 2023.08.18 73
2250 SQL강좌: 5-2. 테이블 생성과 데이터형 선택 [1] 코난(김대우) 2023.08.18 52
2249 SQL강좌: 5-1. SQL Server 테이블 file 코난(김대우) 2023.08.18 67
2248 SQL강좌: 4-8. 시스템 카탈로그 엿보기 file 코난(김대우) 2023.08.18 68
2247 SQL강좌: 4-7. 최적의 데이터베이스 구성 file 코난(김대우) 2023.08.18 74
2246 SQL강좌: 4-6. 데이터베이스의 데이터와 로그 코난(김대우) 2023.08.18 43
2245 SQL강좌: 4-5. 데이터베이스 삭제 file 코난(김대우) 2023.08.18 45
2244 SQL강좌: 4-4. 데이터베이스 옵션 file 코난(김대우) 2023.08.18 84
2243 SQL강좌: 4-3. 데이터베이스 크기조절 file 코난(김대우) 2023.08.18 62
2242 SQL강좌: 4-2. 데이터베이스 생성 file 코난(김대우) 2023.08.18 77
2241 SQL강좌: 4-1. SQL Server 데이터베이스와 데이터베이스 개체의 이해 file 코난(김대우) 2023.08.18 108
2240 SQL강좌: 3-4. TRUNCATE TABLE / 트랜잭션 수행 [1] 코난(김대우) 2023.08.18 86
2239 SQL강좌: 3-3. DELETE를 이용한 로우 삭제 코난(김대우) 2023.08.18 66
2238 SQL강좌: 3-2. UPDATE - 데이터 수정 코난(김대우) 2023.08.18 74
2237 SQL강좌: 3-1. 데이터 삽입, 삭제, 수정 - INSERT를 이용한 행 삽입 코난(김대우) 2023.08.18 90
2236 SQL강좌: 2-14. SQL 쿼리 자동생성 - 쿼리 디자이너 file 코난(김대우) 2023.08.18 97
2235 SQL강좌: 2-13. SELECT 결과셋을 XML, JSON 형식으로 출력 코난(김대우) 2023.08.18 84





XE Login