utf 8 - पीएएलएसयूएलएल एनईएचआरएचएआरएआरएबीई BASE64 से यूटीएफ-8 तक डीकोड करता है



utf-8 plsql (1)

मेरे पास एक ऐसा डेटाबेस है जो इस समय केवल अंग्रेज़ी में उपयोगकर्ता नाम संग्रहीत करता है।

मैं अन्य भाषाओं में भी स्टोर करने के लिए BASE64 और UTF-8 को शामिल करना चाहता हूं; मैं उसे NVARCHAR2 प्रकार के कॉलम में संग्रहीत करना चाहता हूं

डेटाबेस की प्रक्रिया को BASE64 में नाम प्राप्त होता है, मैं इसे UTL_ENCODE.BASE64_DECODE माध्यम से डीकोड कर रहा हूं और स्ट्रिंग को UTL_RAW.CAST_TO_VARCHAR2UTL_RAW.CAST_TO_VARCHAR2 का उपयोग करके VARCHAR2 परिवर्तित कर रहा UTL_RAW.CAST_TO_VARCHAR2 । लेकिन मुझे वाकई वापस आती हैं और वास्तविक शब्द नहीं।

उदाहरण के लिए मुझे BASE64 में नाम के रूप में 'ऐलेक्स' मिलता है I मैं इसे डीकोड करने में सक्षम हूं, लेकिन VARCHAR2/NVARCHAR2 को डाली वैल्यू वापस नहीं करता है: मुझे केवल गपशप मिलता है

मैं NLS_CHARACTERSET WE8ISO8859P1 Oracle 12c पर NLS_CHARACTERSET WE8ISO8859P1 का उपयोग कर रहा हूं

यहां कोड है जिसे मैं डीकोड करने के लिए उपयोग करता हूं:

DECLARE 
  lv_OrgUserName VARCHAR2(2000);
  lv_encodedUserName VARCHAR2(2000);
  lv_UserName    VARCHAR2(2000);
BEGIN 

lv_OrgUserName := 'алекс';
lv_encodedUserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(lv_OrgUserName)));
DBMS_OUTPUT.PUT_LINE (lv_encodedUserName);
lv_UserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW (lv_encodedUserName)));
DBMS_OUTPUT.PUT_LINE (lv_UserName);

END;

मैं इससे कैसे उबरूं?


सबसे पहले और अग्रणी WE8ISO8859P1 (पश्चिमी यूरोपीय 8-बिट आईएसओ 885 9 भाग 1, या - आईएसओ 8859 भाग 1) साइरिलिक वर्णों का समर्थन नहीं करता है:
यह लिंक देखें: https://en.wikipedia.org/wiki/ISO/IEC_8859-1

इसलिए यदि आप алекс तरह स्ट्रिंग को VARCHAR2 चर / कॉलम में संग्रहित करने का प्रयास करते हैं, तो आपको हमेशा a???? मिलेगा a???? एक परिणाम के रूप में

शायद डेटाबेस अधिष्ठापन के दौरान किसी ने cyryllic वर्ण नहीं माना है और एक खराब codepage चुना है
एक बेहतर विकल्प आईएसओ / आईईसी 8859-5 (भाग 5) है, यह लिंक देखें: https://en.wikipedia.org/wiki/ISO/IEC_8859-5

एक विकल्प इस एन्कोडिंग को बदलना है - लेकिन यह आसान नहीं है और यह इस प्रश्न का उत्तरदायित्व है।

आप अपने आवेदन के सभी स्थानों पर VARCHAR2 डेटाटाइप के बजाए NVARCHAR2 डेटाटाइप का सख्ती से उपयोग कर सकते हैं जिसे साइरिलिक वर्णों का समर्थन करना चाहिए।

अभी भी कुछ नुकसान हैं, हालांकि आपको इसके बारे में पता होना चाहिए:

  • आप अपना कोड डिबग करने के लिए DBMS_OUTPUT पैकेज का उपयोग नहीं कर सकते, क्योंकि यह पैकेज केवल VARCHAR2 डेटाटाइप का समर्थन करता है, यह NVARCHAR का समर्थन नहीं करता है
  • आपको सभी N'some string' (एन उपसर्ग के साथ) का उपयोग करना चाहिए -> 'алекс' VARCHAR2 डेटाटाइप का है और इसे हमेशा स्वतः 'a????' बदल दिया जाता है 'a????' आपके एन्कोडिंग में, जबकि n'алекс' NVARCHAR2 डेटाटाइप का है और ऐसा रूपांतरण नहीं होता है।

नीचे दिए गए कोड का संस्करण 12c पर परीक्षण किया गया है, मैं EE8MSWIN1250 कोड पृष्ठ का उपयोग कर रहा हूं (यह साइरिलिक वर्णों का भी समर्थन नहीं करता):

select * from nls_database_parameters
where parameter like '%CHARACTERSET%';

PARAMETER                VALUE
-----------------------  ------------
NLS_NCHAR_CHARACTERSET   AL16UTF16
NLS_CHARACTERSET         EE8MSWIN1250

कृपया इसे एक कोशिश का मौका दीजिए:

CREATE OR REPLACE PACKAGE my_base64 AS
   FUNCTION BASE64_ENCODE( str nvarchar2 ) RETURN varchar2;
   FUNCTION BASE64_DECODE( str varchar2  ) RETURN nvarchar2;
END;
/

CREATE OR REPLACE PACKAGE BODY my_base64 AS

   FUNCTION BASE64_ENCODE( str nvarchar2 ) RETURN varchar2
   IS 
     lv_encodedUserName VARCHAR2(2000);
   BEGIN
    lv_encodedUserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(str)));
    RETURN lv_encodedUserName;
   END;


   FUNCTION BASE64_DECODE( str  varchar2  ) RETURN nvarchar2
   IS
     lv_UserName    nVARCHAR2(2000);
   BEGIN
      lv_UserName := UTL_RAW.CAST_TO_nVARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW (str)));
      RETURN lv_UserName;
   END;

END;
/

कुछ उदाहरण:

select 'aлекс' As A, n'aлекс' As B from dual;

A     B   
----- -----
a???? aлекс
select my_base64.BASE64_ENCODE( n'аaaлекс' ) As aleks from dual;

ALEKS                                                                          
--------------------------------------------------------------------------------
BDAAYQBhBDsENQQ6BEE= 
select my_base64.BASE64_DECODE( 'BDAAYQBhBDsENQQ6BEE=' ) as aleks from dual;

ALEKS                                                                          
--------------------------------------------------------------------------------
аaaлекс   
select my_base64.BASE64_DECODE( my_base64.BASE64_ENCODE( n'аaaлекс' ) ) as Aleks from dual;

ALEKS                                                                          
--------------------------------------------------------------------------------
аaaлекс  




oracle12c