5

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

update

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

update 2

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

1 Answer 1

1

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.

SQL Fiddle

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

Results:

| BYTES |      CHSET | DECODED |
|-------|------------|---------|
|  RUZH | iso-8859-1 |     EFG |
Sign up to request clarification or add additional context in comments.

1 Comment

This was actually just a toy problem to try to understand how to get a java written UDF running in Oracle - it ended up being the silly mistake "byte vs. java.lang.byte" for which Oracle was not giving a very informative error message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.