At least in Oracle 19 this seems to work reliably, too, and it is easier to use than @Jon-Heller 's excellent answer:
WITH values1 AS
(
SELECT
null, 1
FROM
dual
UNION
SELECT
1, null
FROM
dual
), values2 AS
(
SELECT
null, '1'
FROM
dual
UNION
SELECT
'1', null
FROM
dual
)
SELECT
rawtohex(standard_hash(json_object(*))) AS hashed
FROM
values1
UNION ALL
SELECT
rawtohex(standard_hash(json_object(*)))
FROM
values2
yields
HASHED |
34BF2884FD8EE260AEE479600DE7CA27E4AABEDA |
5C91114F78949FDEEC84BCD5FBE4057570CD5149 |
DF54D6C3FD95C4FC3EA274DF50CE22AF28972F04 |
BD5DB32944879E000D14396CF028DDB44C70687F |
... or to use the original example:
SELECT
rawtohex(standard_hash(json_object(*))) AS hashed
FROM
(
SELECT 1 a, 2 b, 3.1 c, 'aa' x FROM dual UNION ALL
SELECT 4 a, 5 b, 6.3 c, 'bb' x FROM dual UNION ALL
SELECT 1 a, 2 b, 9.9 c, 'cc' x FROM dual UNION ALL
--Test with NULL and with flipping column values.
SELECT 1 a, 2 b, 9.9 c, null x FROM dual UNION ALL
SELECT 2 A, 1 b, 9.9 C, 'cc' x FROM dual
) t;
HASHED |
4F7C93B5F106D7E93CD43047F39EA3503509C22A |
B6565A1184308B13ACC1E543D3BD573B4D845958 |
A86E32443F2D81E454151CBFCF64B0D67C7F8C0B |
3A522C3EE28B8D62CD3278D509FD6D4B7DF433B3 |
83299BB84F4FBB28B0F146DA579A831F6DA5C426 |