sqldb2db2-400rpgle

How to cast hex data string to a string db2 sql


How would you decode a hex string to get the value in text format by using a select statement?

For example my data in hex is:

4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000

I want to decode it to get the string value using a select statement. The value of the above is "ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES"

what I have tried is :

    SELECT CAST('4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000' 
    AS VARCHAR(30000) CCSID 37) from myschema.atable

The above sql returns the exact same hex string and not the decoded text string of "ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES" what I expected.

Is it possible to do this with a cast? If it is what will the syntax be?

My problem that I have is a system stores text data in a blob field and I want to use a select statement to see what the text data is in the blob field.

Db : Db2 on Ibm

Edit:

I have managed to covert the string to the hex value by using :

    select hex(cast('ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES' as varchar(100) ccsid 1208))
FROM myschema.atable

This gives me the string in hex :

4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553

Now somehow I need to do the inverse and get the value.

Thanks.

Edit

Using the answer from Daniel Lema, I tried using the unhex function but my result that I got was :

|+<ßã|êâ ä.í&|+<áîá<|+áã|êäê +áë

Is this something to do with a CSSID? Or how should I convet the above to a readable string?

This is the table field definition if it will help the field with my data in is GDTXFT a BLOB :

enter image description here


Solution

  • I was able to take your shortened hex string and convert is to a valid EBCDIC string. The problem I ran into is that the original hex code you receive comes in UTF-16LE (Thanks Tom Blodget). IBM's CCSID system does not have a distinction between UTF-16BE and UTF-16LE so I am at a loss there on how to convert it properly.

    If it is in UTF-8 as you generated later, the following would work for you. It's not the prettiest but throw it in a couple functions and it will work.

    Create or replace function unpivothex (in_ varchar(30000))
        returns table (Hex_ char(2), Position_ int)
        return
        with returnstring (ST , POS )
        as 
        (Select substring(STR,1,2), 1
        from table(values in_) as A(STR)
        union all
        Select nullif(substring(STR,POS+2,2),'00'), POS+2
        from returnstring, table(values in_) as A(STR)
        where POS+2 <= length(in_)
        )
        Select ST, POS 
        from returnstring
        ;
    
    Create or replace function converthextostring
       (in_string char(30000))
       returns varchar(30000)
       return
       (select listagg(char(varbinary_format(B.Hex_),1)) within group(order by In_table.Position_)
       from table(unpivothex(upper(in_string))) in_table
       join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
       join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
       );
    

    Here is a version if you're not on at least V7R2 TR6 or V7R3 TR2.

    Create or replace function converthextostring
       (in_string char(30000))
       returns varchar(30000)
       return
       (select xmlserialize(
                 xmlagg(
                   xmltext(cast(char(varbinary_format(B.Hex_),1) as char(1) CCSID 37)) 
                 order by In_table.Position_) 
               as varchar(30000))
       from table(unpivothex(upper(in_string))) in_table
       join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
       join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
       );