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.

Oracle-Zeichensatzkonvertierung (9): 6. So konvertieren Sie vom Benutzer implementierte Zeichensätze (2)

6.3. So konvertieren Sie den CLOB-Typ in Koreanisch

Oracle-Zeichensatzkonvertierung(8): 6. So konvertieren Sie einen vom Benutzer implementierten Zeichensatz (1)

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.

Oracle Character Set 변환 테스트 테이블 구성
Konfiguration der Oracle-Zeichensatzkonvertierungstesttabelle

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.

ORAUS7 CLOB 데이터 확인
Überprüfen Sie die ORAUS7 CLOB-Daten

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.

ORAUS7 CLOB 한글 데이터 확인 (sqlplus, NLS_LANG=US7ASCII)
Überprüfen Sie ORAUS7 CLOB koreanische Daten (sqlplus, NLS_LANG=US7ASCII)
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.

KO16MSWIN949 CLOB 데이터 확인
Überprüfen Sie die KO16MSWIN949 CLOB-Daten

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.

Überprüfen Sie die ORAUTF-CLOB-Daten

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“.

CLOB 데이터를 DB Link로 query할 때 ORA-22992 오류
ORA-22992 Fehler beim Abfragen von CLOB-Daten mit DB Link
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.

CTAS로 생성한 Table 데이터 확인
Überprüfen Sie die mit CTAS erstellten Tabellendaten

Der Prozess zum Konvertieren koreanischer Zeichen in eine CLOB-Spalte ist wie folgt.

CLOB 컬럼의 한글을 변환하는 과정 요약
Zusammenfassung des Konvertierungsprozesses für koreanische Zeichen in CLOB-Spalten
  1. Erstellen Sie eine Ansicht, die den Datentyp der CLOB-Spalte in der Quell-DB (Instanz #1, ORAUS7) in BLOB konvertiert.
  2. Tabelle mit CTAS-Syntax (Create Table As Select) im Ziel-DB erstellen (Instanz #3, ORAUTF)
  3. 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.

NLS_CHARSET_ID 함수로 BLOB_CSID 확인
Überprüfen Sie BLOB_CSID mit der Funktion NLS_CHARSET_ID
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.

CLOB 한글 변환결과 확인
Überprüfen Sie das Konvertierungsergebnis für CLOB Koreanisch

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.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

de_DEDeutsch