How convert a string to binary in Snowflake? - snowflake-cloud-data-platform

Original byte value in base16 BINARY format -
7e-c2-8c-c2-8a-c7-61-60-34-b7-0e-de-c2-28-9e-b3-08-a6-c3-93-74-99-34-09-48-0c-60-e3-96-47-04-e3
After converting it to VARCHAR - 7EC28CC28AC7616034B70EDEC2289EB308A6C39374993409480C60E3964704E3
I need to convert it back to BINARY and for this I used the TO_BINARY('7EC28CC28AC7616034B70EDEC2289EB308A6C39374993409480C60E3964704E3') function,
but it returns 7EC28CC28AC7616034B70EDEC2289EB308A6C39374993409480C60E3964704E3
instead of the desired 7e-c2-8c-c2-8a-c7-61-60-34-b7-0e-de-c2-28-9e-b3-08-a6-c3-93-74-99-34-09-48-0c-60-e3-96-47-04-e3.
Note - TO_BINARY(string,'base16') doesn't work

You want to strip the hyphens, and use TO_BINARY on 'HEX' input type
SELECT
'7e-c2-8c-c2-8a-c7-61-60-34-b7-0e-de-c2-28-9e-b3-08-a6-c3-93-74-99-34-09-48-0c-60-e3-96-47-04-e3' as tb_b16_str
,replace(tb_b16_str, '-') as no_hyphen
,to_binary(no_hyphen, 'HEX') as now_as_bin
,base64_encode(now_as_bin) as now_as_base64
;
TB_B16_STR
NO_HYPHEN
NOW_AS_BIN
NOW_AS_BASE64
7e-c2-8c-c2-8a-c7-61-60-34-b7-0e-de-c2-28-9e-b3-08-a6-c3-93-74-99-34-09-48-0c-60-e3-96-47-04-e3
7ec28cc28ac7616034b70edec2289eb308a6c39374993409480c60e3964704e3
7ec28cc28ac7616034b70edec2289eb308a6c39374993409480c60e3964704e3
fsKMworHYWA0tw7ewiieswimw5N0mTQJSAxg45ZHBOM=
if we take the BASE64, and paste that into notepad++ and BASE64 decode that, and save that as a bin file and open in a hex editor, we can see sure enough now_as_bin is correct decoded as expected..
You already have a binary:
So thinking about this more, you are already successfully coverting the data to a Snowflake binary:
SELECT '7EC28CC28AC7616034B70EDEC2289EB308A6C39374993409480C60E3964704E3' as hex_str
,system$typeof(hex_str)
,TO_BINARY(hex_str) as now_as_binary
,system$typeof(now_as_binary);
The result you don't like the look of, it's a Snowflake binary.
HEX_STR
SYSTEM$TYPEOF(HEX_STR)
NOW_AS_BINARY
SYSTEM$TYPEOF(NOW_AS_BINARY)
7EC28CC28AC7616034B70EDEC2289EB308A6C39374993409480C60E3964704E3
VARCHAR(64)[LOB]
7ec28cc28ac7616034b70edec2289eb308a6c39374993409480c60e3964704e3
BINARY(8388608)[LOB]
How to export back to teradata:
Or you are really looking for "how to convert a binary to Teradata formatting string for exporting from Snowflake to Teradata"
So the step broken down:
SELECT
'7EC28CC28AC7' as hex_str
,TO_BINARY(hex_str) as now_as_binary
,hex_encode(now_as_binary) as back_to_hex
,REGEXP_REPLACE(back_to_hex, '(..)','\\1-') as made_chunky
,RTRIM(made_chunky, '-') as wanted
;
gives:
HEX_STR
NOW_AS_BINARY
BACK_TO_HEX
MADE_CHUNKY
WANTED
7EC28CC28AC7
7ec28cc28ac7
7EC28CC28AC7
7E-C2-8C-C2-8A-C7-
7E-C2-8C-C2-8A-C7
and that can be mashed together like:
SELECT
TO_BINARY('7EC28CC28AC7') as now_as_binary
,RTRIM(REGEXP_REPLACE(hex_encode(now_as_binary), '(..)','\\1-'), '-') as made_chunky
;
NOW_AS_BINARY
MADE_CHUNKY
7ec28cc28ac7
7E-C2-8C-C2-8A-C7

Related

Does snowflake have a ‘hex’ to ‘int’ type native function?

This FAQ answer says that Snowflake doesn't have a native way to convert from hex to int, and suggests a JS alternative:
https://community.snowflake.com/s/article/faq-does-snowflake-have-a-hex-to-int-type-function
But is there a way to convert from hex to bin with pure SQL in Snowflake?
The FAQ answer is wrong (we are going to fix it soon), as there is a native way to convert hex to int in Snowflake:
select to_number('fff','XXX');
-- 4095
Note that to_number needs to have an hexadecimal format string of at least the length of the hexadecimal input. It can be longer too for safety:
select to_number('fff','XXXXXXXXXXX');
-- 4095
Or you can construct the format string out of the length of the input hex string:
select to_number(h, repeat('X', length(h)))
from (
select 'fff' h
);
-- 4095
select to_number(h, repeat('X', length(h)))
from (
select 'fffffffffffffffffffffffffffffff' h
);
-- 21267647932558653966460912964485513215

How can I output numbers formatted a specific way dynamically in a query? Example: 1.234 might need to be 1.2 or 1.234000

In the database, there is a number (rawresult) and a number format (format) in a single row. I want to format the rawresult to how format says it should be with a single query. This is a database that already exists and we can't modify it.
Example 1: (rawresult = 1.254; format = 0.0), output should be 1.3
Example 2: (rawresult = 1.254; format = 0.00000), output should be 1.25400
Example 3: (rawresult = 10.254; format = 0.000), output should be 10.254
The format field can be null, 0, 0.0, have 6 decimal places, or anything in between. I have no idea how to go about doing this with a single SQL query. Sometimes, format will be null, but that part I can actually handle. Basically, I need to round it if format has less decimal places than rawresult, or add trailing 0s if format requires more decimal places than rawresult has.
Thanks!
A possible approach is the FORMAT() function, but the format must contain a valid .NET Framework format string:
SELECT FORMAT([rawresult], [format]) AS [result]
FROM (VALUES
(1.254, NULL),
(1.254, '0.0'),
(1.254, '0.00000'),
(10.254, '0.000')
) v ([rawresult], [format])
Result:
result
-------
1.254
1.3
1.25400
10.254

Convert HASBYTES function output to CHAR

I know that the best data type for storing output of the HASHBYTES function is BINARY/VARBINARY, but we want to store it as CHAR as it is suggested by DataVault best practices, moreover not all tolls support keys of BINARY types, for example PowerBI.
So the question is, how to convert it to CHAR? When I do simple CAST/CONVERT I get different output rather than raw output of HASHBYTES function.
SELECT CONVERT(CHAR(32), HASHBYTES('MD5', 'test'))
SELECT CAST(HASHBYTES('MD5', 'test') AS CHAR(32))
SELECT HASHBYTES('MD5', 'test')
Expected value is 098F6BCD4621D373CADE4E832627B4F6 (without 0x) and actual value is kÍF!ÓsÊÞNƒ&'´ö
--convert binary to char without 0x prefix, using style 2
SELECT CONVERT(CHAR(32), HASHBYTES('MD5', 'test'), 2);

Why SQL binary convert function results a non-0101... value?

Why when I use the command in SQL Server 2005
select convert(varbinary(16),N'123')
results 0x310032003300 and not 1111011?
Basically each letter of '123' gets converted to it's UCS-2(basically the ASCII value padded to make it a double byte) value in the three double bytes of 0x3100, 0x3200, 0x3300, and concatenated together in a varbinar.
Hopefully that answers why you see this behavior. If you convert to an int first you may see what you were perhaps hoping for instead:
select convert(varbinary(16),cast(N'123' as int))
produces hex value 0x0000007B which in binary is 1111011
See http://www.asciitable.com/ the entry for numeric 3, the hex representation is 0x33 which corresponds to the same entry in unicode: http://www.ssec.wisc.edu/~tomw/java/unicode.html (this pattern does not necessarily hold true for all ASCII/unicode characters, but does for the 10 integers).

Convert hexadecimal value into bigint

I am getting some trouble converting a string (representing a hexadecimal number) into a bigint. I would also like this to happen inside a function and as effiecient as possible.
Is there anyway of exploiting the built-in functions?
Here is an example of what I want to do:
select convert (bigint, '0000010d1858798c')
The SQL Server 2008 release updated the CONVERT() function to be able to convert hexadecimal values:
select convert(bigint, convert (varbinary(8), '0x0000010d1858798c', 1))
Result:
1155754654092 (decimal) ( == 0x0000010d1858798c )

Resources