简体   繁体   中英

Oracle 11g hextoraw sql query results

So, I have a table called mams_folder , where primary key is mams_folder_id .

Now, its type is raw. I am representing keys in hexadecimal string. Following queries were run on sql developer.

Now, I run these queries :

select * from mams_folder f where f.mams_folder_id= hextoraw('EEA12100F39D100384D2080020F03012'); //Works fine

select * from mams_folder f where f.mams_folder_id= 'EEA12100F39D100384D2080020F03012';//Surprisingly works fine too. Why ?

select * from mams_folder f where f.mams_folder_id= hextoraw('5426deaf924642bb9a38dc0b5be87ed6'); //Works fine as expected

select * from mams_folder f where f.mams_folder_id= '5426deaf924642bb9a38dc0b5be87ed6'; //Returns no rows as expected

Both are valid primary keys. '5426deaf924642bb9a38dc0b5be87ed6' was newly inserted in database.

Why does db returns answer to second query but returns null for the last ? Does it have to do something with db caching ?

Update :

Ok, I came to know that if I am using primary keys in uppercase hex string, then even without using hextoraw() , queries work fine (as we can see above). However when smaller case is used, hextoraw() becomes compulsary to use else empty result is shown. Why ?

I believe what you are seeing stems from implicit/explicit type conversion mechanics when inserting by literal or hextoraw then later predicating against a literal.

Formal Hexadecimal is 0123456789ABCDEF (uppercase), radix 16, though there is tooling (both in Oracle and elsewhere) to recognize character strings containing 0123456789abcdefABCDEF (case insensitive) as hex.

HEXTORAW is case-insensitive and accepts lower-case hex. But the returned raw value will be formal hex.

As an example, running the following:

SELECT HEXTORAW('5426deaf924642bb9a38dc0b5be87ed6') AS HEX FROM DUAL;

Gives formal upper-case hex

HEX                               
5426DEAF924642BB9A38DC0B5BE87ED6  

And the following will of course fail, as it contains a non-hex char g

SELECT HEXTORAW('5426geaf924642bb9a38dc0b5be87ed6') FROM DUAL;
ORA-01465: invalid hex number

As will implicit conversion when inserting the above literal into a raw field. RAW requires hex.

For the queries against mams_folder table, I believe the queries with lower-case literal predicates find no matches because when predicating with a string literal, the ensuing type conversion to compare RAW and VARCHAR2 winds up attempting to match formal hex char against lower-case literal char. (It does not convert the provided literal to raw , but compares the hex to the literal)

Since HEXTORAW converts any input string to formal hex in the conversion process, it ends up with a different comparison than the plain literal would anyway, even if it were comparing char instead of raw .

So the simple predicate that matches the converted (upper-case) RAW against a lower-case literal will result in no matches. But when comparing an upper-case literal against the RAW , the formal hex used in comparison happens to match the upper-case string literal and the predicate is fulfilled.

Here's an example:

CREATE TABLE mams_folder (mams_folder_id RAW(32));

Then add the test data. One item is added as an upper-case literal, one added as a lower-case literal, relying on oracle to do any needed type conversion implicitly

INSERT INTO mams_folder VALUES ('EEA12100F39D100384D2080020F03012');
INSERT INTO mams_folder VALUES ('5426deaf924642bb9a38dc0b5be87ed6');

Then just query to see how things look initially. No hextoraw involved yet.

SELECT * FROM MAMS_FOLDER;

MAMS_FOLDER_ID                    
EEA12100F39D100384D2080020F03012  
5426DEAF924642BB9A38DC0B5BE87ED6  

Note the printed value for the inserted literal '5426deaf924642bb9a38dc0b5be87ed6' .

Now the conversion comparing raw to upper-case literal matches.

In this query:

SELECT MAMS_FOLDER_ID, 'EEA12100F39D100384D2080020F03012' AS TARGET FROM MAMS_FOLDER;

We can see that the first row matches the converted raw with the literal.

MAMS_FOLDER_ID                    TARGET                            
EEA12100F39D100384D2080020F03012  EEA12100F39D100384D2080020F03012  
5426DEAF924642BB9A38DC0B5BE87ED6  EEA12100F39D100384D2080020F03012  

With the implicit comparisons matching the formal hex from the RAW against the literal rather than converting the literal to a raw , UPPER would work just fine in a predicate as well.

SELECT * FROM MAMS_FOLDER F WHERE F.MAMS_FOLDER_ID = UPPER('5426DEAF924642BB9A38DC0B5BE87ED6');

MAMS_FOLDER_ID                    
5426DEAF924642BB9A38DC0B5BE87ED6  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM