문자 집합 문제의 초보적인 탐구(3) - 문자 집합의 변경
데이터베이스를 만든 후 문자 집합을 수정해야 한다면 데이터베이스를 재구성하고 가져오고 내보내는 방식으로 변환해야 한다.우리도 다음과 같은 방식으로 변경할 수 있다
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
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의 작업만 완성했다.잠재적인 무결성 위험은 가히 짐작할 수 있다.따라서 문자 집합을 바꾸려면 가능한 한 정상적인 경로를 사용해야 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Control Version de una base de datos OraclePodemos는 Flyway y Liquibase의 새로운 기반 버전을 제어할 수 있는 프로젝트를 제안합니다. Dada la integración de SQLcl y Liquibase, este ejemplo nos...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.