Convert from BINARY directly to INT, bypassing intermediate CHAR - mysql

I'm converting a table that has a column storing integers as hexadecimal strings. I'd like to convert these strings to integers, as they take up less space and are easier to query. However, it seems that MySQL lacks an efficient way to convert from BINARY to INT.
This works:
SELECT CAST(CONV(some_column, 16, -10) AS SIGNED);
-- some_column = "49858170ef9a4f63"
...but it converts to a decimal string first, which is less than ideal. I'd like to convert directly to an integer, bypassing the string:
SELECT CONVERT(UNHEX(some_column), SIGNED);
-- some_column = "49858170ef9a4f63"
...but it doesn't work; I always get 0. It seems to be doing the same thing as CAST.
How can I convert a BINARY value directly to an INT, without first converting it to a string? In a more abstract sense, how can I change the type of a value without changing the underlying data?
Note that this is purely MySQL; I am not using PHP or any other scripting language.

Short of creating your own STORED FUNCTION, I don't think there is way you can avoid converting to a string first.
I am guessing UNHEX is not working because (at least MySQL's official example suggests), HEX/UNHEX convert the string/decimal bytes to/from a hex characters representation, and your hex strings are probably of the '0x???' format, which CONVERT will change to '0'.
Given CONV has to parse the string anyway, I doubt it converting it to a decimal string really requires that much additional overhead.

To INT
conv(substr(hex(segment), -8)
TO ip addr
SELECT INET_NTOA(conv(substr(hex(segment), -8), 16, 10))
Good luck.

Related

ERROR: malformed array literal in PostgreSQL

I want filter on integer array in postgresql but when I am executing below query its giving me malformed array literal error.
select * from querytesting where 1111111111 = any((jsondoc->>'PhoneNumber')::integer[]);
Open image for reference-
https://i.stack.imgur.com/Py3Z2.png
any(x) wants a PostgreSQL array as x. (jsondoc->>'PhoneNumber'), however, is giving you a text representation of a JSON array. A PostgreSQL array would look like this as text:
'{1,2,3}'
but the JSON version you get from ->> would look like:
'[1,2,3]'
You can't mix the two types of array.
You could use a JSON operator instead:
jsondoc->'PhoneNumber' #> 1111111111::text::jsonb
Using -> instead of ->> gives you a JSON array rather than text. Then you can see if the number you're looking for is in that array with #>. The double cast (::text::jsonb) is needed to convert the PostgreSQL number to a JSON number for the #> operator.
As an aside, storing phone numbers as numbers might not be the best idea. You don't do arithmetic on phone numbers so they're not really numbers at all, they're really strings that contain digit characters. Normalizing the phone number format to international standards and then treating them as strings will probably serve you better in the long term.

Ways MySQL/MariaDB could silently be changing values when storing

I'm searching for cases in MySQL/MariaDB where the value transmitted when storing will differ from the value that can be retrieved later on. I'm only interested in fields with non-binary string data types like VARCHAR and *TEXT.
I'd like to get a more comprehensive understanding on how much a stored value can be trusted. This would especially be interesting for cases where the output just lacks certain characters (like with the escape character example below) as this is specifically dangerous when validating.
So, this boils down to: Can you create an input string (and/or define an environment) where this doesn't output <value> in the second statement?
INSERT INTO t SET v = <value>, id = 1; // success
SELECT v FROM t WHERE id = 1;
Things I can think of:
strings containing escaping (\a → a)
truncated if too long
character encoding of the table not supporting the input
If something fails silently probably also depends on how strict the SQL mode is set (like with the last two examples).
Thanks a lot in advance for your input!
you can trust that all databases do, what the standards purpose, with strings and integer it is simple, because it saves the binary representation of that number or character in your choosen character set.
Decimal Double and single values are different, because the can't be saved directly and so it comes to fractals see decimal representation
That also follows standards, but you have to account with it.

Char.IsDigit vs NumberFormat.NativeDigits

I'm working on optimizing my parser for JSON that I built in Visual Basic .NET. I do not follow the EBNF verbatim, for example with numbers I match for an optional positive sign and for boolean/null values I'm not limiting a match to just lower-case. However, I have a question on if I should use Char.IsDigit or NumberFormat.NativeDigits for matching digits in a number.
Currently I use Char.IsDigit because I'm iterating through each character in the source code and so it is just easier to compare the currently iterated Char value in the String. However, to check for the optional positive/negative signs I'm using the NumberFormat class anyways and so I was wondering if there is any benefit to checking if the currently iterated character is in the NativeDigits collection.
The downside that I can think of is that since I am iterating through each Char in the String, that I'd have to convert the Char to a String to check if the character is in the NativeDigits collection; since Strings are immutable in VB.NET I try to make as few instances of Strings as possible.

mysql single quote in arithmatic functions

In mysql, if I do something like
round((amount * '0.75'),2)
it seem to work just fine like without single quotes for 0.75. Is there a difference in how mysql process this?
In the hope to close out this question, here's a link that explains type conversion in expression evaluation: https://dev.mysql.com/doc/refman/5.5/en/type-conversion.html
When an operator is used with operands of different types, type
conversion occurs to make the operands compatible. Some conversions
occur implicitly. For example, MySQL automatically converts numbers to
strings as necessary, and vice versa.
mysql> SELECT 1+'1';
-> 2
In your case, MySQL sees arithmetic and performs implicit conversion on any string contained in the expression. There is going to be an overheard in converting a string to number, but it's negligible. My preference is to explicitly type out a number instead of quoting it. That method has helped me in code clarity and maintainability.

SQL storing MD5 in char column

I have a column of type char(32) where I want to store an MD5 hash key. The problem is i've used SQL to update the existing records using HashBytes() function which creates values like
:›=k! ©úw"5Ýâ‘<\
but when I do the insert via .NET it comes through as
3A9B3D6B2120A9FA772235DDE2913C5C
What do I need to do to get these to match up? Is it the encoding?
HashKey isn't a SQL function, did you mean HASHBYTES? Some actual code would help. SQL appears to be computing the raw binary hash and displaying it as ASCII characters.
.NET is computing the hash, then converting it to hexadecimal (or so it appears). CHAR(32) isn't a good way to store raw binary data, you would want to use the BINARY type.
An Example in SQL:
SELECT SUBSTRING(sys.fn_varbintohexstr(HASHBYTES('MD5',0x2040)),3, 32)
And an Example in .NET:
using (MD5 md5 = MD5.Create())
{
var data = new byte[] { 0x20, 0x40 };
var hashed = md5.ComputeHash(data);
var hexHash = BitConverter.ToString(hashed).Replace("-", "");
Console.Out.WriteLine("hexHash = {0}", hexHash);
}
These will both produce the same value. (Where 0x2040 is sample data).
You can either store the hexadecimal data as CHAR(32), or as BINARY(16). Storing the Binary data is twice as space efficient than storing it as hex. What you should not be doing is storing the binary data as CHAR(16).
It's not clear what you mean by "when I do the insert via .NET" - but you shouldn't be storing binary data just in a raw form, as it looks like your'e doing using HashKey(). (Do you definitely mean HashKey by the way? I can't find a reference for it, but there's HashBytes...)
Two common options are to encode the raw binary data as hex - which it looks like you're doing in the second case - or to use base64. Either way should be easy from .NET (Base64 marginally easier, using Convert.ToBase64String) and you probably just need to find the equivalent SQL Server function.
MD5 is typically stored as in hex encoding. I'd guess that your hashkey() SQL function is not hex encoding the MD5 hash, rather it's just returning the ASCII characters representing the hash. But your .NET method is HEX encoding. If you store your MD5 hashing consistently as HEX (or not - up to you but usually stored as HEX), then the results between the two should always be consistent.
For example, the : symbol from your SQL hash is the first character returned from HashKey(). In the .NET method, the first 2 characters are 3A. 31 is 51 in decimal. ASCII code 51 is the colon (:) character. Similarly, you can work your way through each other character, and do the HEX conversion.
See any ASCII codes table for reference, i.e. http://www.asciitable.com/