Oracle varchar2의 문자열 16진수 값을 표시하시겠습니까?
다른 방식으로 인코딩되지만 표의 단일 열에 보관되는 텍스트에 문제가 있습니다.긴 이야기입니다.MySQL에서 "Select hex(str) from table where"를 수행할 수 있으며 설정한 대로 문자열의 바이트를 정확히 볼 수 있습니다.
Oracle에서 터키어 문자 İ로 시작하는 문자열이 있는데, 이 문자열은 유니코드 문자 0x0130 "LATIN CAPital LETT WITH DOT OVERY"입니다.이것은 유니코드 버전 2.0 책의 인쇄본에 있습니다.UTF-8에서 이 문자는 0xc4b0입니다.
지원해야 하는 매우 오래된 클라이언트 앱이 있습니다.그들은 우리에게 "windows-1254"로 이 텍스트를 보낼 것입니다.우리는 그냥 눈을 감고 보관했다가 나중에 돌려주곤 했습니다.이제 우리는 유니코드가 필요하거나 유니코드가 주어지고 있습니다.
그래서 나는:
SQL> select id, name from table where that thing;
ID NAME
------ ------------------------
746 Ý
Windows-1254의 경우 "İ"가 0xdd이고 Windows-1252의 경우 "0xdd"가 "Ω"이기 때문에 이는 타당합니다.제 터미널은 아마도 일반적인 윈도우-1252로 설정되어 있을 것입니다.
그러나:
SQL> select id, rawtohex(name) from table where that thing;
ID RAWTOHEX(NAME)
------ ------------------------
746 C39D
MySQL에는 hex(name) 함수에 해당하는 것이 없는 것 같습니다.하지만 뭔가를 놓치고 있는 게 분명해요.내가 여기서 뭘 놓쳤지요?
제 자바 코드는 제가 제공한 utf8을 가져가서 utf8 복사본과 windows-1252 복사본을 저장해야 합니다.자바 코드는 다음을 제공합니다.
bytes (utf8): c4 b0
bytes (1254): dd
하지만 저장해보니 클라이언트가 정확한 캐릭터를 얻지 못합니다.Oracle이 실제로 저장한 내용을 확인하려고 하면 위에 표시된 쓰레기가 나옵니다.나는 C39D가 어디서 왔는지 전혀 모릅니다.좋은 의견이라도 있나?
모든 애플리케이션에 ojdbc14.jar가 내장되어 있으며 "Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production"이라는 데이터베이스에 연결 중입니다.
이 함수를 사용하여 Oracle이 데이터를 내부에 저장하는 방법을 확인할 수 있습니다.
당신은 오라클이 어떻게 처리하는지에 대해 오해하고 있는 것 같습니다.VARCHAR2
문자는 변환을 설정합니다. Oracle이 데이터를 물리적으로 저장하는 방식에 영향을 줄 수 없습니다. 또한 아직 저장하지 않은 경우 다음을 읽어보는 것이 좋습니다.절대 최소 모든 소프트웨어 개발자는 유니코드 및 문자 집합에 대해 절대적으로 알고 있어야 합니다.
클라이언트가 Oracle과 바이너리로만 대화합니다.사실 모든 시스템은 이진법으로만 정보를 교환합니다.서로를 이해하려면 두 시스템 모두 사용 중인 언어(문자 집합)를 알아야 합니다.
당신의 경우, 우리는 다음과 같은 일이 일어나는 것을 재구성할 수 있습니다.
- 를 보냅니다.
dd
오라클에 연락해서 그렇다고 합니다.windows-1252
)로 표시됨)1254)
. - Oracle은 문자 집합 테이블을 검색하여 이 데이터가 기호로 변환되는 것을 확인합니다.
Ý
이 문자 집합에서. - Oracle은 이 정보를 논리적으로 테이블에 저장합니다.
은 Oracle에서
UTF-8
은 이 를 이데터다변로환니다합음으로 변환합니다.UTF-8
의 이진Ý
:SQL> SELECT rawtohex('Ý') FROM dual; RAWTOHEX('Ý') -------------- C39D
은 오라저를 저장합니다.
C39D
내부적으로
보시다시피 문제는 첫 번째 단계에서 발생합니다. 설정에 문제가 있습니다.이 문제를 해결하지 않는 한 시스템은 성공적으로 대화할 수 없습니다.
사용 시 변환이 자동으로 수행됩니다.VARCHAR2
이 데이터 유형은 논리 텍스트 기호 인터페이스이기 때문입니다(실제 이진 데이터가 저장되도록 강제하는 제어가 거의 없습니다).
UTF-8에 바이트가 있습니다.
String strFromUTF8 = new String(bytes, "UTF8");
byte[] strInOldStyle = strFromUTF8.getBytes("Cp1254");
MySQL을 사용하면 완료됩니다.저는 이 바이트들을 16진수 문자열로 변환하고 unhex(hexStr)로 업데이트합니다.이렇게 하면 기존 바이트를 막대 열에 넣을 수 있습니다.
Oracle을 사용하여 다음을 수행해야 합니다.
String again = new String(strInOldStyle, "Cp1254");
byte[] nextOldBytes = again.getBytes("UTF8");
이제 다음을 사용하여 업데이트를 수행하고 바이트를 varchar2 열로 가져올 수 있습니다.
update table set colName = UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('hexStr')) where ...
이상하지 않나요?저는 제가 이것을 필요 이상으로 복잡하게 만들었다고 확신합니다.
하지만 우리가 보는 것은 이것입니다.
"İ" in UTF-8 == 0xc4d0
"İ" in Cp1254 == 0xdd == "Ý" in Cp1252
"Ý" in UTF-8 == 0xc3d9
"İ" 문자열을 받고 다음 작업을 수행하면 됩니다.
update table set name = UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('C3D9')) where ...
그러면 우리의 레거시 고객은 우리에게 "I"를 줍니다.그건 효과가 있다.
언급URL : https://stackoverflow.com/questions/18701984/displaying-the-hex-value-of-a-string-from-a-oracle-varchar2
'programing' 카테고리의 다른 글
스크킷 학습 의사 결정 트리에서 의사 결정 규칙을 추출하는 방법은 무엇입니까? (0) | 2023.06.10 |
---|---|
C 전처리기 교체 (0) | 2023.06.10 |
입력 텍스트 상자에서 값 가져오기 (0) | 2023.05.31 |
Rspec에서 특정 테스트만 실행하려면 어떻게 해야 합니까? (0) | 2023.05.31 |
node.js 앱을 백그라운드 서비스로 실행하려면 어떻게 해야 합니까? (0) | 2023.05.31 |