Equivalent of MySQL HEX / UNHEX function in SQL Server? - mysql

Does SQL Server has an equivalent to the HEX and UNHEX MySQl functions?

Update 2022: This is outdated, read about CONVERT() together with binary types.
What are you going to do?
Something like a script generation?
There might be better approaches for your issue, but you do not provide many details...
Not quite as slim but this would work
--This will show up like needed, but it will not be a string
SELECT CAST('abc' AS VARBINARY(MAX))
--this is the string equivalent
SELECT sys.fn_varbintohexstr(CAST('abc' AS VARBINARY(MAX)));
--This will turn the string equivalent back to varbinary
SELECT sys.fn_cdc_hexstrtobin('0x616263')
--And this will return the original string
SELECT CAST(sys.fn_cdc_hexstrtobin('0x616263') AS VARCHAR(MAX));
###One hint
If you deal with UNICODE you can check the changes if you set N'abc' instead of 'abc' and in den final line you'd have to convert '0x610062006300' to NVARCHAR.
###Another hint
If you need this more often you might put this into an UDF, than it is as eays as with MySQL :-)

Related

How to escape a whole sql string instead of escaping each argument?

I use https://github.com/mysqljs/mysql.git library.
I have a mysql db query architecture in which I can not modify the SQL query file one by one to escape each argument for there are too many files, but all the SQL queries will call the query method of a same base mysql instance, so I wonder if I can escape the eventual SQL string in the base mysql query method.
I want to escape the whole SQL string like
select * from tableA where name = 'foo'bar
to
select * from tableA where name = 'foo\'bar'
with some function like mysql_escape("select * from tableA where name = 'foo'bar'") instead of doing this using preparing queries or concating escaped strings.
There isn't a way to do this that wont result in a really inefficient function or some bad hack. Just use parameterized queries, Its basically what they are there for. If you cant use those you use concat strings.
Running mysql_escape on a whole query will require the function to know what characters are part of your query and what characters are part of the input values. You could write some kind of stupid regex to try pull the values from the query and then escape them but its just a bad idea.

How do I convert binary data from MySQL to a string in ColdFusion 11?

I have a field in my MySQL database that is set to data type "BIT". The value in the field is 101101. I am trying to read this value using Coldfusion (version 11)
I simply use the following code:
<cfquery name=q1 datasource=#data_source#>
select * from mytable
</cfquery>
<cfoutput>
#q1.mybitfield#
</cfoutput>
I have tried using CAST and CONVERT on the MySQL side and I have tried CharSetEncodeing on the CF side along with every option of ToString, ToBase64, and ToBinary that I can think of.
I still can not get my output to look like it does in the database.
Actually, I was probably thinking of SQL Server's bit type. For MySQL, a simpler option might be to use the bin() function which:
Returns a string representation of the binary value of N, ...This is equivalent to CONV(N,10,2). Returns
NULL if N is NULL.
For example:
SELECT bin(YourBitColumn) AS YourBitColumn FROM YourTable
... or
SELECT bin(YourBitColumn+0) AS YourBitColumn FROM YourTable
NB: High-order 0 bits are not displayed in the converted value. That applies the CF function as well.
Thanks Leigh for your help. I was never able to get it to work with just one step so I used a two step solution (if you want to call it that). What I ended up doing was setting up my MySQL statement to convert the field to an Unsigned interger (although Decimal or a signed integer would have also worked), then once I read in the decimal value I was able to convert it to binary using your suggestion of FormatBaseN(q1.myfield,2). So thanks for the reminder of FormatBaseN. I had forgotten about that one.
My final code ended up looking like this:
The MySQL statement:
SELECT *, CONVERT(item , UNSIGNED) as di from mytable
And the Coldfusion looked like this:
<cfset d = FormatBaseN(q1.di, 2)>
Edit
After writing this, I decided to go with Leigh's answer above since it was a better solution.

difference between UNHEX and X (MySQL)

What really is the difference between MySQL UNHEX and X when dealing with hexadecimal values in a database?
Eg.
SELECT * FROM test WHERE guidCol IN (UNHEX('hexadecimalstring'));
SELECT * FROM test WHERE guidCol IN (X'hexadecimalstring');
Both gives me exact result set. So is there any difference? Performance implications?
Edit: the underlying type of guidCol is binary of course
UNHEX() is a function, therefore you can do something like
SET #var = '41';
SELECT UNHEX(#var);
SELECT UNHEX(hex_column) FROM my_table;
X, on the other hand, is the syntax for a hexadecimal litteral. You cannot do this:
SET #var = '41';
SELECT X#var; -- error (string litteral expected)
SELECT X'#var'; -- error (`#` is not a hexadecimal digit)
SELECT X(#var); -- returns NULL, not too sure about the reason... [edit: but this is probably why you are inserting NULL values]
SELECT X(hex_column) FROM my_table; -- returns NULL as well
This explains why you always get better performance with X: you are using a language construct instead of a function call. X does not need to evaluate a variable, since it expects a litteral string.
Note that even in MySQL 5.6, the X'' notation has a length limit in the reference mysql client and UNHEX() does not (appear to). I do not know what the limit is for X'', as it is not officially documented but I have encountered it when trying to INSERT a BLOB. With X'' literal, mysql client threw a syntax error with a sufficiently long hex sequence while UNHEX() of the same sequence did not. Obviously, length is not an issue when it comes to an actual GUID, but I figured this is useful for anyone else using this question to answer mysql insertion of binary data in the general case.

mysql: replace \ (backslash) in strings

I am having the following problem:
I have a table T which has a column Name with names. The names have the following structure:
A\\B\C
You can create on yourself like this:
create table T ( Name varchar(10));
insert into T values ('A\\\\B\\C');
select * from T;
Now if I do this:
select Name from T where Name = 'A\\B\C';
That doesn't work, I need to escape the \ (backslash):
select Name from T where Name = 'A\\\\B\\C';
Fine.
But how do I do this automatically to a string Name?
Something like the following won't do it:
select replace('A\\B\C', '\\', '\\\\');
I get: A\\\BC
Any suggestions?
Many thanks in advance.
You have to use "verbatim string".After using that string your Replace function will
look like this
Replace(#"\", #"\\")
I hope it will help for you.
The literal A\\B\C must be coded as A\\\\A\\C, and the parameters of replace() need escaping too:
select 'A\\\\B\\C', replace('A\\\\B\\C', '\\', '\\\\');
output (see this running on SQLFiddle):
A\\B\C A\\\\B\\C
So there is little point in using replace. These two statements are equivalent:
select Name from T where Name = replace('A\\\\B\\C', '\\', '\\\\');
select Name from T where Name = 'A\\\\B\\C';
Usage of regular expression will solve your problem.
This below query will solve the given example.
1) S\\D\B
select * from T where Name REGEXP '[A-Z]\\\\\\\\[A-Z]\\\\[A-Z]$';
if incase the given example might have more then one char
2) D\\B\ACCC
select * from T where Name REGEXP '[A-Z]{1,5}\\\\\\\\[A-Z]{1,5}\\\\[A-Z]{1,5}$';
note: i have used 5 as the max occurrence of char considering the field size is 10 as its mentioned in the create table query.
We can still generalize it.If this still has not met your expectation feel free to ask for my help.
You're confusing what's IN the database with how you represent that data in SQL statements. When a string in the database contains a special character like \, you have to type \\ to represent that character, because \ is a special character in SQL syntax. You have to do this in INSERT statements, but you also have to do it in the parameters to the REPLACE function. There are never actually any double slashes in the data, they're just part of the UI.
Why do you think you need to double the slashes in the SQL expression? If you're typing queries, you should just double the slashes in your command line. If you're generating the query in a programming language, the best solution is to use prepared statements; the API will take care of proper encoding (prepared statements usually use a binary interface, which deals with the raw data). If, for some reason, you need to perform queries by constructing strings, the language should hopefully provide a function to escape the string. For instance, in PHP you would use mysqli_real_escape_string.
But you can't do it by SQL itself -- if you try to feed the non-escaped string to SQL, data is lost and it can't reconstruct it.
You could use LIKE:
SELECT NAME FROM T WHERE NAME LIKE '%\\\\%';
Not exactly sure by what you mean but, this should work.
select replace('A\\B\C', '\', '\\');
It's basically going to replace \ whereever encountered with \\ :)
Is this what you wanted?

Single Quotes in MySQL queries

If I have a MySQL query like:
SELECT this FROM that WHERE id='10'
and
SELECT this FROM that WHERE id=10
both seem to work correctly.
What is the use of the single speech marks in MySQL queries? When is it correct to use them?
When MySQL performs the query, there is an implicit conversion of the argument.
If id is INT, then '10' is cast to an integer.
If id is VARCHAR or another text type, 10 is cast to string.
In both cases both queries will work (unless you are running in STRICT mode).
From a performance point of view, you have to use the right data type (do not use quotes for integer arguments) - the implicit cast adds overhead and in some cases, it may hurt the performance of index lookups.
From security perspective, it easier to always use quotes and mysql_real_escape_string (in case the argument is not quoted, mysql_real_escape_string won't stop any attack, that do not use quotes, for example 'UNION SELECT password FROM users'. However, better approach is to cast your variable to int, when it's expected to be int, or use prepared statements
If the value is a string, you have to use ' or ".
If the value is a number, like in your example, you have not to use ', but MySQL handles it if you put it around 's.
Assuming that id is a numeric column, what happens is that MySQL casts your parameter to number automatically so data types match before comparing. It works flawlessly unless casting provides unexpected results. E.g., these expressions with match the row with id=10 because all the strings cast to 10:
id='10'
id=' 10'
id='00010'
id='10foo'
The following will not match the row because non-parseable strings cast to 0 and 10<>0:
id='foo10'
id='bar'
When to use each? If you want a string, you need to quote it (there's no other way to type a string and get valid SQL). If you want a number, it must be unquoted (otherwise, you'll get a string that happens to contain a number). Of course, you can always provide numbers as strings and let MySQL do the conversion, but it doesn't really add anything to the query apart from one extra step and possibly incorrect results that go unnoticed.
You should always use them. They can help to stop SQL injection attacks because mysql_real_escape_string isn't enough on its own.
That is assuming you are running a query via PHP.