문자 집합 문제의 초보적인 탐구(3) - 문자 집합의 변경

2. 문자 세트 변경 내용
데이터베이스를 만든 후 문자 집합을 수정해야 한다면 데이터베이스를 재구성하고 가져오고 내보내는 방식으로 변환해야 한다.우리도 다음과 같은 방식으로 변경할 수 있다

ALTER DATABASE CHARACTER SET


주의: 데이터베이스 문자 집합을 수정할 때는 반드시 신중해야 하며, 수정하기 전에 반드시 데이터베이스에 백업해야 한다.이 작업을 되돌릴 수 없기 때문에 데이터가 분실되거나 손상될 수 있습니다.이것은 문자 집합을 가장 간단하게 변환하는 방식이지만, 항상 유효하지는 않다.이 명령은 Oracle8에서 Oracle로 도입되었습니다. 이 동작은 본질적으로 데이터베이스 문자를 변환하지 않고 데이터베이스에 있는 모든 문자 집합과 관련된 정보를 간단하게 업데이트합니다.
이것은 새로운 문자 집합이 낡은 문자 집합이 엄격하게 초과된 상황에서만 이런 방식으로 변환할 수 있다는 것을 의미한다.하이퍼집합이란 현재 문자 집합의 모든 문자를 새 문자 집합에서 표시할 수 있고 같은 코드점을 사용한다. 예를 들어 많은 문자 집합은 US7 ASCII의 엄격한 하이퍼집합이다.
하이퍼세트가 아닌 경우 다음 오류가 발생합니다.

SQL> ALTER DATABASE CHARACTER SET ZHS16CGB231280;
ALTER DATABASE CHARACTER SET ZHS16CGB231280
*
ERROR at line 1:
ORA-12712: new character set must be a superset of old character set
다음은 Oracle9.2.0에서 진행된 테스트입니다. Oracle9i는 Oracle8i에 비해 인코딩에 큰 변화가 있었고 Oracle8i에서는 결과가 약간 다를 수 있습니다.
SQL> select name,value$ from props$ where name like '%NLS%';

NAME                           VALUE$
------------------------------ ------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               US7ASCII
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
……………….
NLS_NCHAR_CHARACTERSET         AL16UTF16
NLS_RDBMS_VERSION              9.2.0.4.0

20 rows selected.
SQL> select name,dump(name) from eygle.test;

NAME   DUMP(NAME)
------------------------------------------------------
       Typ=1 Len=4: 178,226,202,212
Test      Typ=1 Len=4: 116,101,115,116


2 rows selected.
문자 세트를 변환하려면 데이터베이스가 RESTRICTED 모드에서 수행되어야 합니다.
c:\>sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.4.0 - Production on Sat Nov 1 10:52:30 2003

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> STARTUP MOUNT;
ORACLE instance started.

Total System Global Area   76619308 bytes
Fixed Size                   454188 bytes
Variable Size              58720256 bytes
Database Buffers           16777216 bytes
Redo Buffers                 667648 bytes
Database mounted.
SQL> ALTER SESSION SET SQL_TRACE=TRUE;

Session altered.

SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;

System altered.

SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

System altered.

SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;

System altered.

SQL> ALTER DATABASE OPEN;

Database altered.

SQL> set linesize 120
SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
ALTER DATABASE CHARACTER SET ZHS16GBK
*
ERROR at line 1:
ORA-12721: operation cannot execute when other sessions are active


SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;
ALTER DATABASE CHARACTER SET ZHS16GBK
*
ERROR at line 1:
ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists

 Oracle9i ,       CLOB    ,              

SQL>
    
    

이때, 우리는alert를 보러 갈 수 있다.로그 파일은 CLOB 필드가 있는 테이블을 보여줍니다.

ALTER DATABASE CHARACTER SET ZHS16GBK
SYS.METASTYLESHEET (STYLESHEET) - CLOB populated
ORA-12716 signalled during: ALTER DATABASE CHARACTER SET ZHS16GBK...
서로 다른 상황에 따라 Oracle은 서로 다른 해결 방안을 제공한다. 만약에 사용자 데이터 테이블이라면 CLOB 필드를 포함하는 테이블을 내보낸 다음drop은 관련 대상을 제거하고 변환한 후에 데이터베이스를 가져올 수 있다.시스템 테이블의 경우 다음과 같이 처리할 수 있습니다.

SQL> truncate table Metastylesheet;
Table truncated.


그리고 계속 전환할 수 있어요!


SQL> ALTER SESSION SET SQL_TRACE=TRUE;

Session altered.

SQL> ALTER DATABASE CHARACTER SET ZHS16GBK;

Database altered.

SQL> ALTER SESSION SET SQL_TRACE=FALSE;

Session altered.
    
    
9.2.0에서 전환이 완료된 후catmet을 실행할 수 있습니다.Metastylesheet 테이블을 재구성하는 sql 스크립트:

SQL> @?/rdbms/admin/catmet.sql
변환된 데이터:

SQL> select name,value$ from props$ where name like '%NLS%'; NAME VALUE$ ------------------------------ ------------------------------ NLS_LANGUAGE AMERICAN NLS_TERRITORY AMERICA NLS_CURRENCY $ NLS_ISO_CURRENCY AMERICA NLS_NUMERIC_CHARACTERS ., NLS_CHARACTERSET ZHS16GBK ….. NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_RDBMS_VERSION 9.2.0.4.0 20 rows selected. SQL> select * from eygle.test; NAME ------------------------------ test 2 rows selected.
팁: sql 설정trace, 우리는 많은 데이터베이스의 백엔드 조작을 추적할 수 있습니다. 이 도구는 DBA에서 자주 사용하는 '유리한 도구' 중의 하나입니다.우리는 데이터베이스에서 문자 집합을 변경할 때의 백엔드 처리를 간단하게 보았고, 나는 주요 업데이트 부분을 추출했다.다음 추적 과정을 통해 우리는 데이터베이스가 문자 집합을 변경할 때 주로 12장의 데이터 사전표를 업데이트하고 데이터베이스의 원래 데이터를 수정한 것을 보았다. 이것은 우리가 이전에 말한 바와 같다. 이 문자 집합을 변경하는 작업은 본질적으로 어떠한 데이터 라이브러리 문자도 변환하지 않고 데이터베이스에 있는 모든 문자 집합과 관련된 정보를 간단하게 업데이트하는 것이다.
update col$ set charsetid = :1 
where
 charsetform = :2


update argument$ set charsetid = :1 
where
 charsetform = :2


update collection$ set charsetid = :1 
where
 charsetform = :2


update attribute$ set charsetid = :1 
where
 charsetform = :2


update parameter$ set charsetid = :1 
where
 charsetform = :2


update result$ set charsetid = :1 
where
 charsetform = :2


update partcol$ set spare1 = :1 
where
 charsetform = :2


update subpartcol$ set spare1 = :1 
where
 charsetform = :2


update props$ set value$ = :1 
where
 name = :2


update "SYS"."KOTAD$" set SYS_NC_ROWINFO$ = :1 
where
 SYS_NC_OID$ = :2

update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
  cache=:7,highwater=:8,audit$=:9,flags=:10 
where
 obj#=:1

update kopm$ set metadata = :1, length  = :2 
where
 name='DB_FDO'
    
    

여기서 우리는 유래와 잘못된 방법을 바로잡는 김에이러한 문자 세트 변경 방법은 인터넷에서 자주 볼 수 있습니다.
4


1) SYS     ORACLE。
2) 문자세트 내용 SQL>SELECT* FROM PROPS$보기;3) 수정 문자 세트 SQL> 업데이트 props$set value$='새 문자 세트'where name='NLSCHARACTERSET' 4) COMMIT;
우리는 많은 사람들이 이 문제에 대해 참혹한 교훈을 얻었다. 이런 방식으로 문자 집합을 바꾸는 것을 보았다. 만약에value$값이 부정확한 문자 집합을 입력했다면 8i에서 데이터베이스를 시작할 수 없을 수도 있다. 이런 상황은 매우 심각하다. 때로는 백업에서 복구해야 한다.만약 9i에 있다면 데이터베이스를 다시 시작한 후에 정확한 문자 집합을 수정할 수 있습니다.그러나 우리는 여전히 이런 방식으로 어떠한 데이터베이스 수정도 하는 것을 건의하지 않는다. 이것은 매우 위험한 작업이다.실제로 우리가 문자 집합을 업데이트하면 데이터베이스가 시작될 때 데이터베이스의 문자 집합에 따라 자동으로 제어 파일의 문자 집합을 수정한다. 만약에 문자 집합이 식별할 수 있다면 제어 파일의 문자 집합을 업데이트하는 것은 데이터베이스 문자 집합과 같다.문자 세트가 인식되지 않으면 제어 파일 문자 세트가 US7 ASCII로 업데이트됩니다.
props$표를 업데이트하는 방식으로 문자 집합을 수정합니다. Oracle7 이후에는 사용할 수 없습니다.
다음은 저의 테스트 결과입니다. 그러나 백업하지 않은 모든 수정 연구를 엄금합니다. 설령 테스트 라이브러리에 대한 것이라도.
SQL> update props$ set value$='EYGLE' where name='NLS_CHARACTERSET';

1 row updated.

SQL> commit;

Commit complete.

SQL> select name,value$ from props$ where name like '%NLS%';

NAME                           VALUE$
------------------------------ -----------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               EYGLE
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
….
NLS_NCHAR_CHARACTERSET         ZHS16GBK
NLS_RDBMS_VERSION              8.1.7.1.1

18 rows selected.

       ,  alert.log         :

Mon Nov 03 16:11:35 2003
Updating character set in controlfile to US7ASCII
Completed: ALTER DATABASE OPEN

             :

SQL> update props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';

1 row updated.

SQL> commit;

Commit complete.

SQL> select name,value$ from props$ where name like '%NLS%';

NAME                           VALUE$
------------------------------ -----------------------------------
NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_CURRENCY                   $
NLS_ISO_CURRENCY               AMERICA
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               ZHS16GBK
NLS_CALENDAR                   GREGORIAN
NLS_DATE_FORMAT                DD-MON-RR
NLS_DATE_LANGUAGE              AMERICAN
………
NLS_COMP                       BINARY
NLS_NCHAR_CHARACTERSET         ZHS16GBK
NLS_RDBMS_VERSION              8.1.7.1.1

18 rows selected.

        ,             :

Mon Nov 03 16:21:41 2003
Updating character set in controlfile to ZHS16GBK
Completed: ALTER DATABASE OPEN

 
문자 집합 조정의 내부 조작을 이해한 후에 우리는 위와 같은 방법이 정확하지 않다는 것을 쉽게 지적할 수 있다. 앞의'Alter DATABASE CHARACTER SET'방식을 통해 문자 집합을 변경할 때 Oracle은 적어도 12장의 데이터 사전표를 변경해야 한다. 이런 직접 업데이트props$표의 방식은 그 중 12분의 1의 작업만 완성했다.잠재적인 무결성 위험은 가히 짐작할 수 있다.
따라서 문자 집합을 바꾸려면 가능한 한 정상적인 경로를 사용해야 한다.

좋은 웹페이지 즐겨찾기