Given this table in Oracle
create table test (bytes raw(100), chset varchar2(50))
insert into test (bytes, chset) values (hextoraw('454647'), 'iso-8859-1')
or in MSSQL
create table test (bytes varbinary(100), chset nvarchar(50))
insert into test (bytes, chset) values (0x454647, 'iso-8859-1')
I'm looking for a comprehensive example of how to create a UDF for Oracle in Java that makes use of Java's text encoding support.
In MSSQL I would create this .Net assembly:
using System.Text;
using Microsoft.SqlServer.Server;
namespace Whatever
{
public class Common
{
[SqlFunction]
public static string Decode(byte[] Bytes, string EncodingName)
{
return Encoding.GetEncoding(EncodingName).GetString(Bytes);
}
}
}
and use these commands to register the assembly and define the udf:
create assembly MyAssembly from '...\MyAssembly.dll'
create function decode(@bytes varbinary(max), @chset nvarchar(100))
returns nvarchar(max) as external name MyAssembly.[Whatever.Common].Decode
and use it in a query like this:
> select *, dbo.decode(bytes, chset) decoded from test
bytes chset decoded
0x454647 iso-8859-1 EFG
so far I've created this Java class:
import java.nio.*;
import java.nio.charset.*;
public class Common
{
public static String Decode(byte[] Bytes, String CharsetName)
{
return Charset.forName(CharsetName).decode(ByteBuffer.wrap(Bytes)).toString();
}
}
and used these commands to create the UDF:
create directory jdir as 'C:\...';
create java class using bfile (jdir, 'Common.class');
create function jdecode(bytes raw, chset varchar2) return nvarchar2 as language java
name 'Common.Decode(java.lang.byte[], java.lang.String) return java.lang.String';
but when I try to use it I get this error:
> select jdecode(hextoraw('454647'), 'iso-8859-1') from dual
ORA-29531: no method Decode in class Common
turns out java.lang.byte[] isn't a thing, changing it to just byte[] got things working. Thanks Tim!
create function jdecode(bytes raw, chset varchar2) return nvarchar2 as language java
name 'Common.Decode(byte[], java.lang.String) return java.lang.String';
there's a handy table here: http://download.oracle.com/docs/cd/B19306_01/java.102/b14187/chsix.htm#BABJIJEB
Do you really need a user defined function (UDF) java or otherwise when oracle already provides sufficient utilities for such conversions?
The UTL_I18N
package supplies all the needed functionality. The MAP_CHARSET
funtion maps from ISO character set names to Oracle character set names, then the RAW_TO_CHAR
function converts your raw data of the specified character set to a VARCHAR2
in the database character set.
Oracle 11g R2 Schema Setup:
create table test (bytes raw(100), chset varchar2(50));
insert into test (bytes, chset) values (hextoraw('454647'), 'iso-8859-1');
Query 1:
select t.*
, UTL_I18N.RAW_TO_CHAR( bytes
, UTL_I18N.MAP_CHARSET(chset,0,1)) decoded
from test t
| BYTES | CHSET | DECODED |
|-------|------------|---------|
| RUZH | iso-8859-1 | EFG |