org online google codebeautify and utf-8 plsql oracle12c

utf-8 - online - https codebeautify org base64 decode



PLSQL decodifica NVARCHAR2 de BASE64 a UTF-8 (1)

Tengo una base de datos que almacena nombres de usuarios solo en inglés en este momento.

Me gustaría incorporar BASE64 y UTF-8 para almacenar en otros idiomas también; Quiero almacenarlo en una columna de tipo NVARCHAR2 .

El procedimiento de la base de datos recibe el nombre en BASE64 , lo estoy decodificando a través de UTL_ENCODE.BASE64_DECODE y convirtiendo la cadena en VARCHAR2 usando UTL_RAW.CAST_TO_VARCHAR2 . Pero recupero el galimatías y no la palabra real.

Por ejemplo, obtengo ''алекс'' como el nombre en BASE64 . Puedo descifrarlo pero el molde a VARCHAR2/NVARCHAR2 no devuelve el valor: obtengo solo un galimatías.

Me estoy ejecutando en Oracle 12c usando NLS_CHARACTERSET WE8ISO8859P1

Aquí está el código que uso para decodificar:

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;

¿Cómo puedo superar esto?


En primer lugar, WE8ISO8859P1 (Western European 8-bit ISO 8859 Parte 1, o - ISO8859 Parte 1) no es compatible con caracteres cyryllic:
vea este enlace: https://en.wikipedia.org/wiki/ISO/IEC_8859-1

Por lo tanto, si intenta almacenar una cadena como алекс en la variable / columna VARCHAR2 , siempre obtendrá a???? como resultado.

Probablemente durante la instalación de la base de datos, alguien no haya considerado los caracteres cyryllic y haya elegido una página de códigos incorrecta.
Una mejor opción es ISO / IEC 8859-5 (parte 5), consulte este enlace: https://en.wikipedia.org/wiki/ISO/IEC_8859-5

Una opción es cambiar esta codificación, pero esto no es fácil y es una de las causas de esta pregunta.

Lo que puede hacer es usar estrictamente el tipo de datos NVARCHAR2 en lugar del tipo de datos VARCHAR2 en todos los lugares de su aplicación que deben admitir caracteres cirílicos.

Todavía hay algunas dificultades que debes tener en cuenta:

  • No puede usar el paquete DBMS_OUTPUT para depurar su código, ya que este paquete solo admite el tipo de datos VARCHAR2, no es compatible con NVARCHAR
  • debe usar N''some string'' literales N''some string'' (con el prefijo N) en todos los literales -> ''алекс'' es del tipo de datos VARCHAR2 y siempre se convierte automáticamente en ''a????'' en su codificación, mientras que n''алекс'' es del tipo de datos NVARCHAR2 y dicha conversión no ocurre.

El código siguiente está probado en la versión 12c, estoy usando la página de códigos EE8MSWIN1250 (también no admite caracteres cirílicos):

select * from nls_database_parameters where parameter like ''%CHARACTERSET%''; PARAMETER VALUE ----------------------- ------------ NLS_NCHAR_CHARACTERSET AL16UTF16 NLS_CHARACTERSET EE8MSWIN1250

Por favor inténtalo:

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; /

Algunos ejemplos:

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лекс