Is there a way to disable escape characters in a MySQL query? For example, for the following table:
mysql> select * from test1;
+------------------------+-------+
| name | value |
+------------------------+-------+
| C:\\media\data\temp\ | 1 |
| C:\\media\data\temp | 2 |
| /unix/media/data/temp | 3 |
| /unix/media/data/temp/ | 4 |
+------------------------+-------+
I want the following to be a valid query:
mysql> select * from test1 where name='C:\\media\data\temp\';
I know that I can instead use
mysql> select * from test1 where name='C:\\\\media\\data\\temp\\';
But I am building this query using my_snprintf(), so there instead I have to use
C:\\\\\\\\media\\\\data\\\\temp\\\\
...and so on!
Is there a way to disable escape characters for a single MySQL query ?
You can disable backslash escapes by setting NO_BACKSLASH_ESCAPES in the SQL mode:
-- save mode & disable backslashes
SET #old_sql_mode=##sql_mode;
SET ##sql_mode=CONCAT_WS(',', ##sql_mode, 'NO_BACKSLASH_ESCAPES');
-- run the query
SELECT 'C:\\media\data\temp\';
-- enable backslashes
SET ##sql_mode=#old_sql_mode;
For tabular output in MySQL command line, the “boxing” around columns enables one column value to be distinguished from another. For non-tabular output (such as is produced in batch mode or when the --batch or --silent option is given), special characters are escaped in the output so they can be identified easily. Newline, tab, NUL, and backslash are written as \n, \t, \0, and \. The --raw option disables this character escaping.
Related
(tested on MySQL / MariaDB):
Why does this result in an empty string?
SELECT REGEXP_REPLACE('', '.*', 'hello');
The same with this:
SELECT REGEXP_REPLACE('', '(.*)', '\\1 hello');
On the other hand, if you apply REGEXP with the same regular expression to an empty field, it matches the columns, e.g.
SELECT uid,f1 FROM table1 WHERE f1 REGEXP '.*' and uid=1;
+-----+-----+
| uid | f1 |
+-----+-----+
| 1 | |
+-----+-----+
I would assume, if it matches, it should replace as well. Other regular expression engines work like that, e.g.
echo "" | perl -p -e "s/.*/hello/"
hello
tested on
MySQL 8.0.26
MariaDB 10.4.19
I had been working with REGEXP_REPLACE and I noticed this. The example has been simplified.
It does not work in MySQL (8.0.5+) using ICU-REGEXP to perform a search on the word boundary.
As far as I understand it should be a-la
$ mysql -e 'SELECT REGEXP_LIKE("aaa abc ccc", ".*\b+abc\b+.*")'
+---------------------------------------------+
| REGEXP_LIKE("aaa abc ccc", ".*\b+abc\b+.*") |
+---------------------------------------------+
| 0 |
+---------------------------------------------+
but this option does not work.
First, note that REGEXP_REPLACE can match strings partially, and you do not need .* before and after a search word.
The \ char should be escaped in order to define a literal backslash, since \ itself allows escaping characters for the MySQL engine. See this MySQL 8 documentation:
Note
Because MySQL uses the C escape syntax in strings (for example, \n to represent the newline character), you must double any \ that you use in your expr and pat arguments.
Thus, you need
REGEXP_LIKE("aaa abc ccc", "\\babc\\b")
It does not work in MySQL (8.0.5+) using ICU-REGEXP to perform a search on the word boundary.
As far as I understand it should be a-la
$ mysql -e 'SELECT REGEXP_LIKE("aaa abc ccc", ".*\b+abc\b+.*")'
+---------------------------------------------+
| REGEXP_LIKE("aaa abc ccc", ".*\b+abc\b+.*") |
+---------------------------------------------+
| 0 |
+---------------------------------------------+
but this option does not work.
First, note that REGEXP_REPLACE can match strings partially, and you do not need .* before and after a search word.
The \ char should be escaped in order to define a literal backslash, since \ itself allows escaping characters for the MySQL engine. See this MySQL 8 documentation:
Note
Because MySQL uses the C escape syntax in strings (for example, \n to represent the newline character), you must double any \ that you use in your expr and pat arguments.
Thus, you need
REGEXP_LIKE("aaa abc ccc", "\\babc\\b")
I am trying to fetch rows from my database by checking if the json in one of their fields contains a specific id.
Example: col(kats): [2,4,7,9]
I am trying to do so by using the following query
SELECT column FROM table WHERE column REGEXP '(\[|\,)1(\]|\,)'
The Problem: MySQL returns 1 for every row in the table.
MySQL requires that any literal backslash \ characters (which are literal in the REGEXP string as escape characters to the following []) be escaped themselves. Thus, you must double-escape [] as \\[ and \\].
From the docs:
Because MySQL uses the C escape syntax in strings (for example, “\n” to represent the newline character), you must double any “\” that you use in your REGEXP strings.
The rest of your pattern is basically correct, except that the comma , does not require escaping.
1 does not match:
> SELECT '[2,4,7,9]' REGEXP '(\\[|,)1(\\]|,)';
+--------------------------------------+
| '[2,4,7,9]' REGEXP '(\\[|,)1(\\]|,)' |
+--------------------------------------+
| 0 |
+--------------------------------------+
1 row in set (0.00 sec)
But 2 does match
> SELECT '[2,4,7,9]' REGEXP '(\\[|,)2(\\]|,)';
+--------------------------------------+
| '[2,4,7,9]' REGEXP '(\\[|,)2(\\]|,)' |
+--------------------------------------+
| 1 |
+--------------------------------------+
1 row in set (0.00 sec)
Is it possible to display query results like below within mysql shell?
mysql> select code, created_at from my_records;
code created_at
1213307927 2013-04-26 09:52:10
8400000000 2013-04-29 23:38:48
8311000001 2013-04-29 23:38:48
3 rows in set (0.00 sec)
instead of
mysql> select code, created_at from my_records;
+------------+---------------------+
| code | created_at |
+------------+---------------------+
| 1213307927 | 2013-04-26 09:52:10 |
| 8400000000 | 2013-04-29 23:38:48 |
| 8311000001 | 2013-04-29 23:38:48 |
+------------+---------------------+
3 rows in set (0.00 sec)
The reason I'm asking because I have some tedious task that I need to copy the output and paste it on other tool.
--raw, -r
For tabular output, the “boxing” around columns enables one column value to be distinguished from another. For nontabular output (such as is produced in batch mode or when the --batch or --silent option is given), special characters are escaped in the output so they can be identified easily. Newline, tab, NUL, and backslash are written as \n, \t, \0, and \\. The --raw option disables this character escaping.
The following example demonstrates tabular versus nontabular output and the use of raw mode to disable escaping:
% mysql
mysql> SELECT CHAR(92);
+----------+
| CHAR(92) |
+----------+
| \ |
+----------+
% mysql --silent
mysql> SELECT CHAR(92);
CHAR(92)
\\
% mysql --silent --raw
mysql> SELECT CHAR(92);
CHAR(92)
\
From MySQL Docs
Not exactly what you need, but it might be useful. Add \G at the end of the query
select code, created_at from my_records\G;
Query result will look like this:
*************************** 1. row ***************************
code: 1213307927
created_at: 2013-04-26 09:52:10
*************************** 2. row ***************************
code: 8400000000
created_at: 2013-04-29 23:38:48
One-liner
mysql -u YOURUSER -p --password=YOURPASSWORD -s -r -e "show databases;"
mysql -u root -p --password=abc12345 -s -r -e "show databases;"
You need to pass the -s parameter mysql -s.
mysql --skip-column-names --silent --raw --execute "select * from somewhere;"
To make these the default options for your user, add the following to ~/.my.cnf
skip_column_names
silent
raw
I solved this but using concat_ws to join the results together and then add a space (first argument)
select concat_ws (' ',ipNetFull,ipUsage,broadcast,gateway) from ipNets;
If you want to get MySQL client output without the surrounding table, you can run your query from the linux command line instead of through the mysql client:
$ echo "SELECT CONCAT_WS(' ','DROP TABLE',TABLE_NAME,';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%';" | mysql dbname
bonus: you can pipe the output through sort and stuff, or even back into mysql:
$ echo "SELECT CONCAT_WS(' ','DROP TABLE',CONCAT_WS('.',TABLE_SCHEMA,TABLE_NAME),';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'i\'m\_not\_that\_mean';" | mysql | mysql;
Quick Workaround:
Using the more recent MySQL clients (not sure which versions), you can use the PAGER directive to manipulate the results. Note that you may have to change the sed expression to avoid clobbering your data.
> PAGER sed 's/|//g'
PAGER set to 'sed 's/|//g''
barracuda#db-ess-rw.us-east-2.ess.aws.vt2.com [ess]
> SELECT 'row1_col1' AS column1, 'row1_col2' AS column2
UNION ALL SELECT 'row2_col1', 'row2_col2';
+---------+---------+
column1 column2
+---------+---------+
row1_col1 row1_col2
row2_col1 row2_col2
+---------+---------+
2 rows in set (0.00 sec)
Beefore you do this, you may want to get the current value of your PAGER:
> PAGER
PAGER set to 'less'
To reset to using 'less' as the PAGER
> PAGER less
PAGER set to 'less'
More fun with PAGER:
https://www.percona.com/blog/2013/01/21/fun-with-the-mysql-pager-command/
So confused by the question and answers. ran sql and result kept displaying without lines or non tabular format. Later realized there is an option when you right click on the query space, navigate to "results to" > "results to grid". This Should set it back to tabular format.
There is also an option for "results to text" which was the format I was experiencing.
:)!