열 길이를 수정 (축소)하면 어떻게됩니까?


10

유형 NUMBER(정밀도 및 스케일 제외) 및 의 두 열이 있다고 가정 해 보겠습니다 VARCHAR(300). 이 열이 데이터에 비해 너무 큰 것을 보았으므로 NUMBER(11)및 로 수정하고 싶습니다 VARCHAR(10). 따라서이 SQL 문을 실행하면 :

ALTER TABLE FOO
    MODIFY(BAR NUMBER(10));
  • 비어 있지 않은 열에서 그렇게 할 수 있습니까?
  • 그렇다면, 하나보다 큰 값이 있으면 NUMBER(10)오라클이 그것에 대해 알려줄 것입니까?
  • 이전에 정의한 경우 열 기본값이 변경되지 않습니까?
  • 열 Null 허용 옵션이 변경되지 않습니까?
  • 해당 열의 기본 외래 고유 키가 변경되지 않습니까?
  • 해당 열과 관련된 제약 조건이 변경되지 않습니까?
  • 해당 열의 색인이 변경되지 않습니까?

질문에 대답하는 공식 문서가 있습니까?

답변:


12

오라클 관리자 가이드는 다음을 말한다 :

기존 컬럼 정의를 수정하려면 ALTER TABLE ... MODIFY 문을 사용하십시오. 열 데이터 형식, 기본값, 열 제약 조건, 열 식 (가상 열의 경우) 및 열 암호화를 수정할 수 있습니다.

기존의 모든 데이터가 새 길이를 만족하는 경우 기존 열의 길이를 늘리거나 줄일 수 있습니다. 바이트 시맨틱에서 CHAR 시맨틱으로 또는 그 반대로 열을 변경할 수 있습니다. 비어 있지 않은 CHAR 열의 길이를 줄이려면 초기화 매개 변수 BLANK_TRIMMING = TRUE를 설정해야합니다.

데이터 유형 CHAR의 컬럼 길이를 늘리기 위해 테이블을 수정하는 경우, 이는 시간이 많이 걸리는 조작 일 수 있으며 특히 테이블에 많은 행이 포함 된 경우 상당한 추가 스토리지가 필요할 수 있음을 인식하십시오. 새 열 길이를 만족 시키려면 각 행의 CHAR 값을 공백으로 채워야하기 때문입니다.

오라클 SQL 언어 참조는 다음을 포함하여 더 자세한 내용을 가지고 :

열의 모든 행에 널이 포함 된 경우 열의 데이터 유형을 변경할 수 있습니다. 그러나 구체화 된보기 컨테이너 테이블에서 열의 데이터 유형을 변경하면 Oracle Database는 해당 구체화 된보기를 무효화합니다.

모든 행에 널이 포함되어 있는지 여부에 관계없이 문자 또는 원시 열의 크기 나 숫자 열의 정밀도를 늘릴 수 있습니다. 변경시 데이터를 수정하지 않아도되는 한 열의 데이터 유형 크기를 줄일 수 있습니다. 데이터베이스는 기존 데이터를 스캔하고 새 길이 제한을 초과하는 데이터가있는 경우 오류를 리턴합니다.

DATE 열을 TIMESTAMP 또는 TIMESTAMP WITH LOCAL TIME ZONE으로 수정할 수 있습니다. TIMESTAMP WITH LOCAL TIME ZONE을 DATE 열로 수정할 수 있습니다.

테이블이 비어 있으면 날짜 필드 또는 간격 열의 선행 필드 또는 분수 초 값을 늘리거나 줄일 수 있습니다. 테이블이 비어 있지 않으면 날짜 시간 또는 간격 열의 선행 필드 또는 분수 초만 증가시킬 수 있습니다.

CHAR 및 VARCHAR2 열의 경우 CHAR (원래 바이트로 지정된 열의 문자 의미를 나타냄) 또는 BYTE (원래 문자로 지정된 열의 바이트 의미를 나타냄)를 지정하여 길이 의미를 변경할 수 있습니다. 기존 컬럼의 길이 의미를 학습하려면 ALL_, USER_ 또는 DBA_TAB_COLUMNS 데이터 사전보기의 CHAR_USED 컬럼을 조회하십시오.

위의 설명서에는 추가 정보와 제한 사항이 있습니다. 다음은 숫자 열의 정밀도를 줄이고 Varchar2의 길이를 줄이는 방법을 보여줍니다. 다른 변경 사항을 시도하여 어떤 일이 발생하는지 알 수 있습니다.

--Setup.
DROP TABLE FOO;
CREATE TABLE FOO (BAR Number, BAR2 VARCHAR2(300));
INSERT INTO FOO (SELECT Level, RPAD(to_char(Level),10*Level,to_char(Level)) 
   FROM DUAL CONNECT BY Level <=20);
COMMIT;
SELECT * FROM FOO;

--Reduce Number to Number(10).
ALTER TABLE FOO MODIFY (BAR NUMBER (10));

--Reduce Varchar2(300) to Varchar2(100) (data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100));

--Reduce Varchar2(300) to Varchar2(200) (no data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(200));

alter 문에는 다음과 같은 출력이 있습니다.

ALTER TABLE FOO MODIFY (BAR NUMBER (10))
Error report:
SQL Error: ORA-01440: column to be modified must be empty to decrease precision or scale
01440. 00000 -  "column to be modified must be empty to decrease precision or scale"

ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100))
Error report:
SQL Error: ORA-01441: cannot decrease column length because some value is too big
01441. 00000 -  "cannot decrease column length because some value is too big"

table FOO altered.

새 열을 만들어 정밀도를 줄입니다.

ALTER TABLE FOO ADD (BAR3 NUMBER(10));
UPDATE FOO SET Bar3 = Bar;
ALTER TABLE FOO DROP COLUMN BAR;
ALTER TABLE FOO RENAME COLUMN BAR3 TO BAR;

결론은-열의 정밀도 또는 스케일을 줄이고 인덱스, 키 등과 같은 것을 유지하려면 테이블을 복사하고 자르고 유형을 변경하고 데이터를 다시 복사하여 삭제하는 것입니다 임시 테이블. 더 빠르고 더 우아한 방법이 없습니까?
mnowotka

1
글쎄, 새 열을 만들고, 데이터를 복사하고, 인덱스를 다시 만들고, 이전 열을 삭제하고 새 열의 이름을 바꿀 수 있습니다. DBMS_REDEFINITION을 사용하거나 새 테이블을 작성하고 데이터를 복사하고 이전 테이블을 삭제하고 새 테이블의 이름을 바꿀 수도 있습니다. 또는 테이블을 내보내고 삭제 한 후 새 정의로 다시 작성하여 데이터를 가져올 수 있습니다. 이를 수행하는 방법에는 여러 가지가 있지만 더 빠르고 더 우아하게 결정해야합니다.
레이 리펠

아마도 새 열을 만들고, 데이터를 복사하고, 이전 열을 null로 설정하고, 길이를 수정하고, 새 열의 데이터를 변경된 이전 열로 다시 복사 한 다음 새 열을 삭제할 수도 있습니다. 오라클은 데이터가 적합하더라도 숫자 열을 줄일 수 없기 때문에이 모든 것이 가능합니다. 8- {
Hans-Peter Störr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.