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.