Konvertierung von Oracle-Zeichensätzen (10): 6.3. So konvertieren Sie den CLOB-Typ in Koreanisch
Werfen wir einen Blick auf die koreanische Konvertierungsmethode vom Typ CLOB. In der US7ASCII-Zeichensatz-DB können Sie überprüfen, wie der CLOB-Typ einschließlich Hangul in AL32UTF8 und das Konvertierungsergebnis konvertiert wird.
Dies ist eine Fortsetzung des vorherigen Artikels.
6.3. So konvertieren Sie den CLOB-Typ in Koreanisch
Im obigen Artikel habe ich folgendes erwähnt:
Als Referenz: Bei der Konvertierung von US7ASCII in AL32UTF8 werden Spalten vom Typ CLOB nicht normal konvertiert, sodass eine separate Verarbeitung erforderlich ist.
Es wird im nächsten Artikel erklärt.
In diesem Artikel erklären wir, wie Sie den Typ CLOB einschließlich koreanischer Zeichen mithilfe von DB Link von US7ASCII in AL32UTF8 in AL32UTF8 konvertieren. Verwenden Sie DBMS_LOB, ein Oracle-Basispaket.
Lassen Sie uns zunächst CLOB-Daten von drei Instanzen überprüfen: ORAUS7, ORAMSWIN949 und ORAUTF.
6.3.1. Überprüfen Sie die CLOB-Daten
Füllen Sie die CLOB-Spalte (REF_DES) mit Daten, indem Sie die folgende INSERT-Anweisung auf drei Instanzen ausführen: ORAUS7, ORAMSWIN949 und ORAUTF.
INSERT INTO SUB_MON_STAT (USE_MON, LINE_NUM, SUB_STA_ID, SUB_STA_NM, RIDE_PASGR_NUM, ALIGHT_PASGR_NUM, WORK_DT, COMMT, REF_DES, REF_IMG) VALUES ('201301', '1호선', '0150', '서울역', 2199181, 1855268, '20130723', RPAD('서울역', 3000, '서울역'), RPAD('서울역', 3000, '서울역'), UTL_RAW.CAST_TO_RAW('12345')) ;
Der Datentyp jeder Spalte ist wie folgt.
Lassen Sie uns nun die Daten der ref_des-Spalte (CLOB-Typ) in jeder Instanz mit dem folgenden SQL überprüfen.
select dbms_lob.getlength(ref_des) chr_len ,lengthb(dbms_lob.substr(ref_des, dbms_lob.getlength(ref_des), 1)) byte_len ,dump(dbms_lob.substr(ref_des, dbms_lob.getlength(ref_des), 1), 1016) dp ,ref_des from sub_mon_stat where ref_des is not null and rownum <= 1 ;
▼ ORAUS7
Der Zeichensatz der CLOB-Daten ist US7ASCII, und koreanische Zeichen werden nicht normal angezeigt.
Die Anzahl der Zeichen (chr_len) beträgt 3.000 und die Anzahl der Bytes (byte_len) ebenfalls 3.000. Das heißt, es ist ersichtlich, dass ein Zeichen als ein Byte gespeichert wird.
Ich konnte keine Möglichkeit finden, NLS_LANG in SQL Developer festzulegen, also habe ich es in sqlplus ausgeführt und bestätigt, dass koreanische Zeichen angezeigt wurden.
Wenn NLS_LANG wie unten gezeigt auf US7ASCII eingestellt ist, wird Koreanisch angezeigt.
C:\Users\ymlee>set NLS_LANG=AMERICAN_AMERICA.US7ASCII C:\Users\ymlee>sqlplus leg/leg@oraus7 SQL*Plus: Release 11.2.0.1.0 Production on Sun Jul 24 21:42:43 2022 Copyright (c) 1982, 2010, Oracle. All rights reserved. Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> set pagesize 100 SQL> set linesize 200 SQL> select dbms_lob.getlength(ref_des) chr_len 2 ,lengthb(dbms_lob.substr(ref_des, dbms_lob.getlength(ref_des), 1)) byte_len 3 ,substr(dump(dbms_lob.substr(ref_des, dbms_lob.getlength(ref_des), 1), 1016), 1, 200) dp 4 ,ref_des 5 from sub_mon_stat 6 where ref_des is not null 7 and rownum <= 1 8 SQL> / CHR_LEN BYTE_LEN ---------- ---------- DP -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- REF_DES -------------------------------------------------------------------------------- 3000 3000 Typ=1 Len=3000 CharacterSet=US7ASCII: bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa,bc,ad,bf,ef,bf,aa, 서울역서울역서울역서울역서울역서울역서울역서울역서울역서울역서울역서울역서울역서 SQL>
▼ ORAMSWIN949
Der Zeichensatz der CLOB-Daten ist KO16MSWIN949, und koreanische Zeichen werden normal angezeigt.
Die Anzahl der Zeichen (chr_len) beträgt 1.500 und die Anzahl der Bytes (byte_len) beträgt 3.000. Das heißt, es ist ersichtlich, dass ein Zeichen als 2 Bytes gespeichert wird.
▼ ORAUTF
Der Zeichensatz der CLOB-Daten ist AL32UTF8, und koreanische Zeichen werden normal angezeigt.
Die Anzahl der Zeichen (chr_len) beträgt 1.334 und die Anzahl der Bytes (byte_len) beträgt 4.000. Das heißt, es ist ersichtlich, dass ein Zeichen als 3 Bytes gespeichert wird.
(Die genaue Anzahl der Bytes beträgt 4.002, aber es gibt einen kleinen Unterschied, da die maximale Anzahl der von dbms_lob.substr zurückgegebenen Bytes 4.000 beträgt.)
6.3.2. CLOB-Datenkonvertierung
CLOB-Daten können keine Auswahl über DB Link ausführen. Ich erhalte die Fehlermeldung „ORA-22992: Ausgewählter LOB-Speicherort aus Remote-Tabelle kann nicht verwendet werden“.
select use_mon, line_num, sub_sta_id, sub_sta_nm, ride_pasgr_num, alight_pasgr_num, work_dt, commt ,ref_des from sub_mon_stat@dl_us7 a ; ORA-22992: 원격 테이블로 부터 선택된 LOB 위치를 사용할 수 없습니다 22992. 00000 - "cannot use LOB locators selected from remote tables" *Cause: A remote LOB column cannot be referenced. *Action: Remove references to LOBs in remote tables.
Sie können Daten mithilfe der CTAS-Syntax (Create Table As Select) wie folgt kopieren.
create table sub_mon_stat_from_oraus7 as select use_mon, line_num, sub_sta_id, sub_sta_nm, ride_pasgr_num, alight_pasgr_num, work_dt ,ref_des from sub_mon_stat@dl_us7 a ; select dbms_lob.getlength(ref_des) chr_len ,lengthb(dbms_lob.substr(ref_des, 1333, 1)) byte_len ,dump(dbms_lob.substr(ref_des, 1333, 1), 1016) dp ,ref_des from sub_mon_stat_from_oraus7 where ref_des is not null and rownum <= 1 ;
Betrachtet man das obige Abfrageausführungsergebnis, wurde der Zeichensatz der CLOB-Spalte in AL32UTF8 konvertiert, aber die koreanische Zeichenfolge wurde nicht normal konvertiert.
Der Prozess zum Konvertieren koreanischer Zeichen in eine CLOB-Spalte ist wie folgt.
- Erstellen Sie eine Ansicht, die den Datentyp der CLOB-Spalte in der Quell-DB (Instanz #1, ORAUS7) in BLOB konvertiert.
- Tabelle mit CTAS-Syntax (Create Table As Select) im Ziel-DB erstellen (Instanz #3, ORAUTF)
- Erstellen Sie eine Tabelle, indem Sie den BLOB-Datentyp der oben erstellten Tabelle in den CLOB-Typ konvertieren
Schauen wir sie uns nacheinander an.
1. Erstellen Sie eine Ansicht, die den Datentyp der CLOB-Spalte in der Quell-DB (Instanz #1, ORAUS7) in BLOB konvertiert.
Wird der Datentyp der CLOB-Spalte auf BLOB konvertiert, wird der Zeichensatz bei der Abfrage mit DB Link nicht konvertiert.
Erstellen Sie eine Funktion, die CLOB mithilfe der DBMS_LOB.CONVERTTOBLOB-Prozedur wie folgt in BLOB konvertiert.
CREATE OR REPLACE FUNCTION FN_CLOB_TO_BLOB (P_CLOB CLOB) RETURN BLOB AS L_BLOB BLOB; L_DEST_OFFSET INTEGER := 1; L_SOURCE_OFFSET INTEGER := 1; L_LANG_CONTEXT INTEGER := DBMS_LOB.DEFAULT_LANG_CTX; L_WARNING INTEGER := DBMS_LOB.WARN_INCONVERTIBLE_CHAR; BEGIN IF DBMS_LOB.GETLENGTH(P_CLOB) != 0 THEN DBMS_LOB.CREATETEMPORARY(L_BLOB, TRUE); DBMS_LOB.CONVERTTOBLOB ( DEST_LOB =>L_BLOB, SRC_CLOB =>P_CLOB, AMOUNT =>DBMS_LOB.LOBMAXSIZE, DEST_OFFSET =>L_DEST_OFFSET, SRC_OFFSET =>L_SOURCE_OFFSET, BLOB_CSID =>DBMS_LOB.DEFAULT_CSID, LANG_CONTEXT=>L_LANG_CONTEXT, WARNING =>L_WARNING ); END IF; RETURN L_BLOB; END;
Erstellen Sie dann eine Ansicht mit der obigen Funktion.
Zu Testzwecken wurden nur Zeilen mit Werten in einigen Spalten und der CLOB-Spalte REF_DES ausgewählt.
CREATE OR REPLACE VIEW VW_SUB_MON_STAT_BLOB AS SELECT USE_MON, SUB_STA_ID ,FN_CLOB_TO_BLOB(REF_DES) REF_DES_BLOB FROM SUB_MON_STAT WHERE REF_DES IS NOT NULL;
2. Erstellen Sie eine Tabelle mit CTAS-Syntax (Create Table As Select) im Ziel-DB (Instanz #3, ORAUTF)
Holen Sie sich Daten von DB Link mit der folgenden Syntax und erstellen Sie eine Tabelle.
CREATE TABLE SUB_MON_STAT_BLOB AS SELECT A.* FROM VW_SUB_MON_STAT_BLOB@DL_US7 A;
3. Erstellen Sie eine Tabelle, indem Sie den BLOB-Datentyp der oben erstellten Tabelle in den CLOB-Typ konvertieren
Erstellen Sie eine Funktion, die BLOB in CLOB konvertiert, indem Sie die DBMS_LOB.CONVERTTOCLOB-Prozedur wie folgt verwenden.
CREATE OR REPLACE FUNCTION FN_BLOB_TO_CLOB (P_BLOB BLOB) RETURN CLOB AS L_CLOB CLOB; L_DEST_OFFSET INTEGER := 1; L_SOURCE_OFFSET INTEGER := 1; L_LANG_CONTEXT INTEGER := DBMS_LOB.DEFAULT_LANG_CTX; L_WARNING INTEGER := DBMS_LOB.WARN_INCONVERTIBLE_CHAR; BEGIN DBMS_LOB.CREATETEMPORARY(L_CLOB, TRUE); DBMS_LOB.CONVERTTOCLOB ( DEST_LOB =>L_CLOB, SRC_BLOB =>P_BLOB, AMOUNT =>DBMS_LOB.LOBMAXSIZE, DEST_OFFSET =>L_DEST_OFFSET, SRC_OFFSET =>L_SOURCE_OFFSET, --BLOB_CSID =>DBMS_LOB.DEFAULT_CSID, BLOB_CSID =>846, -- NLS_CHARSET_ID('KO16MSWIN949') LANG_CONTEXT=>L_LANG_CONTEXT, WARNING =>L_WARNING ); RETURN L_CLOB; END;
Unter den Parametern der DBMS_LOB.CONVERTTOCLOB-Prozedur bedeutet BLOB_CSID „Die Zeichensatz-ID der Quelldaten“.
Weitere Einzelheiten entnehmen Sie bitte dem unten stehenden Dokument.
DBMS_LOB – CONVERTTOCLOB-Prozedur (oracle.com)
BLOB_CSID muss als ganzzahliger Wert und nicht als Zeichenfolge angegeben werden, und der Wert kann mit der Funktion NLS_CHARSET_ID ermittelt werden.
Da der Zeichensatz der Originaldaten KO16MSWIN949 ist, wurde 846 durch Ausführen des Folgenden bestätigt.
SELECT NLS_CHARSET_ID('KO16MSWIN949') FROM DUAL;
Und Sie können eine Tabelle mit der obigen Funktion erstellen oder abfragen.
CREATE TABLE SUB_MON_STAT_BLOB_TO_CLOB AS SELECT USE_MON, SUB_STA_ID ,FN_BLOB_TO_CLOB(REF_DES_BLOB) REF_DES FROM SUB_MON_STAT_BLOB A; select * from sub_mon_stat_blob_to_clob ; -- Table 생성하지 않을 경우는 다음과 같이 query 가능 select use_mon, sub_sta_id ,fn_blob_to_clob(ref_des_blob) ref_des from sub_mon_stat_blob ;
Sie können wie folgt überprüfen, ob Hangul normal konvertiert wurde.
Bisher haben wir uns angesehen, wie man den Typ CLOB inklusive koreanischer Zeichen in der US7ASCII-Zeichensatz-DB nach AL32UTF8 konvertiert.
Es sieht etwas kompliziert aus, da es durch mehrere Prozesse konvertiert wird, aber es ist nicht schwierig, wenn Sie es Schritt für Schritt betrachten.
Bis zu diesem Artikel ist die Serie über die Oracle-Zeichensatzkonvertierung abgeschlossen.
Ich hoffe, ich kann jemandem helfen, der es braucht.