Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie finden Sie mit sql/plsql heraus, welchen Zeichensatz ein Text verwendet?

Oracle Globalization Development Kit kann Zeichensätze erkennen.

Das GDK ist in Oracle enthalten, wird jedoch standardmäßig nicht in der Datenbank installiert. Um die .jar-Dateien in die Datenbank zu laden, suchen Sie das jlib-Verzeichnis im Oraclehome und führen Sie diesen Betriebssystembefehl aus:

loadjava -u [email protected] orai18n.jar orai18n-collation.jar orai18n-lcsd.jar orai18n-mapping.jar orai18n-net.jar orai18n-servlet.jar orai18n-tools.jar orai18n-translation.jar orai18n-utility.jar

Einige zusätzliche Java-Berechtigungen sind erforderlich, selbst wenn Ihr Benutzer DBA hat. Führen Sie diesen Befehl aus und verbinden Sie sich erneut:

exec dbms_java.grant_permission( 'YOUR_USER_NAME', 'SYS:java.lang.RuntimePermission', 'getClassLoader', '' );

Erstellen Sie eine Java-Klasse, um die Erkennung durchzuführen. Unten ist ein sehr einfaches Beispiel, das die beste Schätzung für eine Zeichenfolge zurückgibt:

create or replace and compile java source named "Character_Set_Detector"
as
import oracle.i18n.lcsd.*;
import java.sql.*;
import java.io.IOException;
public class Character_Set_Detector
{
    public static String detect(Blob some_blob) throws SQLException, IOException
    {
        LCSDetector detector = new LCSDetector();
        detector.detect(some_blob.getBinaryStream());
        LCSDResultSet detector_results = detector.getResult();
        return detector_results.getORACharacterSet();
    }
}
/

Schließen Sie die Java-Klasse in eine PL/SQL-Funktion ein:

--Wrap the Java class in a PL/SQL function:
create or replace function detect_character_set(some_blob blob)
return varchar2
as language java
name 'Character_Set_Detector.detect(java.sql.Blob) return java.lang.String';
/

Ich habe verschiedene Zeichensätze simuliert, indem ich einen String in verschiedene Sprachen übersetzte, den Text als verschiedene Kodierungen mit einem Texteditor speicherte, die Datei mit einem Hex-Editor öffnete und das Hex in ein BLOB konvertierte:

--UTF8
--The quick brown fox jumps over the lazy dog
select 1 id, detect_character_set(hextoraw('54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67')) character_set from dual union all
--Western European (ISO-8859-1)
--El zorro marrón rápido salta sobre el perro perezoso
select 2 id, detect_character_set(hextoraw('456c207a6f72726f206d617272f36e2072e17069646f2073616c746120736f62726520656c20706572726f20706572657a6f736f')) from dual union all
--Chinese Simplified (GBK)
--敏捷的棕色狐狸跳过懒狗
select 3 id, detect_character_set(hextoraw('c3f4bdddb5c4d7d8c9abbafcc0eaccf8b9fdc0c1b9b7')) from dual union all
--Western European (Windows-1252)
--Der schnelle braune Fuchs springt über den faulen Hund
select 4 id, detect_character_set(hextoraw('446572207363686e656c6c6520627261756e6520467563687320737072696e677420fc6265722064656e206661756c656e2048756e64')) from dual union all
--Cyrillic (KOI8-R)
--Быстрая коричневая лиса прыгает через ленивую собаку
select 5 id, detect_character_set(hextoraw('e2d9d3d4d2c1d120cbcfd2c9decec5d7c1d120ccc9d3c120d0d2d9c7c1c5d420dec5d2c5da20ccc5cec9d7d5c020d3cfc2c1cbd5')) from dual;

ID  CHARACTER_SET
--  -------------
1   US7ASCII
2   WE8ISO8859P1
3   ZHS16CGB231280
4   WE8ISO8859P1
5   CL8KOI8R

Dieses triviale Beispiel funktioniert gut, aber ich weiß nicht, wie gut es mit realen Dateien funktionieren wird. Es gibt viele Funktionen im GDK, der obige Code ist nur ein einfacher Ausgangspunkt. Mit nur geringfügigen Änderungen kann der Code auch Sprachen erkennen, wie in meiner Antwort hier gezeigt .