In MySQL, when I try to insert a backslash into my table, it does not accept it and gives me the content without the backslash.
id is set to auto increment:
Code:
INSERT INTO gender (sex, date) VALUES (
'male are allowed \ female are not allowed', "2012-10-06")
How do I insert a literal backslash?
Notes about escape sequences:
Escape Sequence Character Represented by Sequence
\0 An ASCII NUL (0x00) character.
\' A single quote (“'”) character.
\" A double quote (“"”) character.
\b A backspace character.
\n A newline (linefeed) character.
\r A carriage return character.
\t A tab character.
\Z ASCII 26 (Control+Z). See note following the table.
\\ A backslash (“\”) character.
\% A “%” character. See note following the table.
\_ A “_” character. See note following the table.
You need to escape your backslash :
INSERT INTO gender
(sex, date) VALUES (
'male are allowed \\ female are not allowed',
"2012-10-06")
Reference (with the list of all characters you must escape for mysql)
Handle backslashes and all control characters in mysql load data infile tool:
Step 1, create your table:
mysql> create table penguin (id int primary key, chucknorris VARCHAR(4000));
Query OK, 0 rows affected (0.01 sec)
Step 2, create your file to import and put this data in there.
1 spacealiens are on route
2 scramble the nimitz\
3 \its species 8472
4 \\\\\\\\\\\\\\\\\\
5 Bonus characters:!##$%^&*()_+=-[]\|}{;'":/.?>,< anything but tab
Step 3, insert into your table:
mysql> load data local infile '/home/el/foo/textfile.txt' into table penguin
fields terminated by '\t' lines terminated by '\n'
(#col1, #col2) set id=#col1, chucknorris=#col2;
Query OK, 4 rows affected, 1 warning (0.00 sec)
Records: 4 Deleted: 0 Skipped: 0 Warnings: 1
Step 4, and of course, it causes this strange output:
mysql> select * from penguin;
+----+-----------------------------------------------------------------+
| id | chucknorris |
+----+-----------------------------------------------------------------+
| 1 | spacealiens are on route |
| 2 | scramble the nimitz |
| 3 | |
| 4 | \\\\\\\\\ |
| 5 | Bonus characters:!##$%^&*()_+=-[]|}{;'":/.?>,< anything but tab |
+----+-----------------------------------------------------------------+
Step 5, analyze the warning:
mysql> show warnings;
+---------+------+--------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------- ------------------+
| Warning | 1262 | Row 2 was truncated; it contained more data than there |
| | | were input columns |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)
Step 6, think about exactly what went wrong:
The backslash to the left of nimitz caused the mysql load data parser to concatenate the end of line 2 with the beginning of line 3. Then it bumped up against a tab and put 'scramble the nimitz\n3 into row 2.
The rest of row 3 is skipped because the extra words its species 8472 do not fit anywhere, it produces the warning you see above.
Row 4 had 18 backslashes, so there is no problem, and shows up as 9 backslahes because each was escaped. Had there been an odd number, the error on row 2 would have happened to row 4.
The bonus characters on row 5 came through normally. Everything is allowed except tab.
Step 7, reset table penguin:
mysql> delete from penguin;
Step 8, load into your table with the fields escaped by clause:
mysql> load data local infile '/home/el/foo/textfile.txt' into table penguin
fields terminated by '\t' escaped by '\b'
lines terminated by '\n' (#col1, #col2) set id=#col1,
chucknorris=#col2;
Query OK, 5 rows affected (0.00 sec)
Records: 5 Deleted: 0 Skipped: 0 Warnings: 0
Step 9, select from your table, interpret the results:
mysql> select * from penguin;
+----+------------------------------------------------------------------+
| id | chucknorris |
+----+------------------------------------------------------------------+
| 1 | spacealiens are on route |
| 2 | scramble the nimitz\ |
| 3 | \its species 8472 |
| 4 | \\\\\\\\\\\\\\\\\\ |
| 5 | Bonus characters:!##$%^&*()_+=-[]\|}{;'":/.?>,< anything but tab |
+----+------------------------------------------------------------------+
5 rows in set (0.00 sec)
And now everything is as we expect. The backslash at the end of line 2 does not escape the newline. The backslash before i on row 3 doesn't do anything. The 18 backslashes on row 4 are not escaped. And the bonus characters come through ok.
you can use this code :
$yourVariable = addcslashes($_POST["your param"],"\\");
for example in my web form i want insert local directory :
$localAddress = addcslashes($_POST["localAddress"],"\\");
Related
I am trying to get, post and put JSON data to a MYSQL server (docker container) that uses utf8 as the charset. Within this JSON data are strings that should contain "\n". When the data is applied in my application these "\n" are causing linebreaks which is what I want.
But when I try to insert this into my database it throws an error: "ERROR 3140 (22032) at line x: "Invalid JSON text: "Invalid encoding in string.".
Solutions I found suggested adding additional backslashes (" '\' \n"). While this works for inserting, it doesn't allow for the linebreaks I wanted in my application. Is there some way around without changing the application ?
SQL Query:
INSERT INTO table (id, json) VALUES (1,'{"data": "name: ab \n cost: 5 $ | time: 1 s"}')
INSERT INTO table (id, json) VALUES (1,'{"data": "name: ab \n cost: 5 $ | time: 1 s"}')
\n is a escape sequence in SQL so you're sending an actual carriage return character rather than a backslash followed by letter n, which is what JSON mandates. It's more obvious with this other query:
mysql> select '{"data": "name: ab \n cost: 5 $ | time: 1 s"}' as test;
+----------------------------------------------+
| test |
+----------------------------------------------+
| {"data": "name: ab
cost: 5 $ | time: 1 s"} |
+----------------------------------------------+
1 row in set (0.00 sec)
To insert a literal \ in MySQL you need to escape with another \:
mysql> select 'one\\ntwo' as test;
+----------+
| test |
+----------+
| one\ntwo |
+----------+
1 row in set (0.00 sec)
Please note this is only an issue when you type literal strings in your code. It won't affect data coming from other sources (e.g. HTML forms or databases) unless you fail to process it somewhere (e.g. by injecting it in raw SQL rather than using prepared statements).
Hello i need a regular expression per my sql query to match to text
"SIP/(10 NUMBERS)"
equals
"SIP/1234567890"
"SIP" are text
and 10 number randoms 0-9
UPDATE
Final text are SIP/0123456789-000001cc
where
"SIP/" is text
"0123456789" Always 10 digits
"-" is character
"000001cc" is random alphanumeric
You can use this regex:
^SIP/[[:digit:]]{10}-
Examples:
mysql> select 'SIP/0123456789-000001cc' regexp '^SIP/[[:digit:]]{10}-';
+----------------------------------------------------------+
| 'SIP/0123456789-000001cc' regexp '^SIP/[[:digit:]]{10}-' |
+----------------------------------------------------------+
| 1 |
+----------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select 'SIP/123456789-000001cc' regexp '^SIP/[[:digit:]]{10}-';
+----------------------------------------------------------+
| 'SIP/123456789-000001cc' regexp '^SIP/[[:digit:]]{10}-' |
+----------------------------------------------------------+
| 0 |
+----------------------------------------------------------+
1 row in set (0.00 sec)
Use \ to escape /
The following RegEx targets SIP followed by /and then 10 digit characters:
SIP\/\d{10}
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)
Why does this match (it should match (44[0-9]) zero or more times)
mysql> SELECT "tampampam" REGEXP "(44[0-9])*$";
+----------------------------------+
| "tampampam" REGEXP "(44[0-9])*$" |
+----------------------------------+
| 1 |
+----------------------------------+
1 row in set (0.00 sec)
And this does not (it should match 44 followed by ([0-9]) zero or more times
mysql> SELECT "44tampampam" REGEXP "44([0-9])*$";
+------------------------------------+
| "44tampampam" REGEXP "44([0-9])*$" |
+------------------------------------+
| 0 |
+------------------------------------+
1 row in set (0.00 sec)
Well, it is a very strange regex expression.
As for the first case, (44[0-9])*$ means "match a string starting with 44 and then a number from 0 to 9, any number of times up to the end of string". Since "any number" is possible, the string "tampampam" is matched.
As for the second case, 44([0-9])*$ means "match 44, then any number from 0 to 9 (with heavy backtracking), zero or more times, up to the end of string". But after 44 there is "tampampam". No match is due. Remove $, and you'll have a match.
You must use start anchor also to make sure it doesn't match unwanted text:
SELECT "tampampam" REGEXP "^(44[0-9])*$";
+-----------------------------------+
| "tampampam" REGEXP "^(44[0-9])*$" |
+-----------------------------------+
| 0 |
+-----------------------------------+
The first query matches because matching something zero or more times, means that not matching it (ie. matching zero times), is also a match.
The second query does not match, because you have anchored the regular expression to the end of the string, because of the dollar-sign ($). As the end of the string is not the string 44 optionally followed by digits, it does not match.
I see no reason to use *$ in your case. Keep it simple:
SELECT "tampampam" REGEXP "44[0-9]";
=> 0
SELECT "t441ampampam" REGEXP "44[0-9]";
=> 1
SELECT "t441ampampam" REGEXP "^44[0-9]";
=> 0
SELECT "441tampampam" REGEXP "^44[0-9]";
=> 1
So if you need 44 to be the first characters in the string use '^44[0-9]'.
If you don't care that is as simple as '44[0-9]'.
I'm trying to get this CSV file that I exported from excel loaded into my database and I can't seem to get the formatting correct no matter what I try.
Here is the SQL:
LOAD DATA INFILE 'path/file.csv'
INTO TABLE tbl_name
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(column1, column2, column3);
This works fine but then I run into trouble when the end of a line (column 3) ends in a quote. For example:
Actual value: These are "quotes"
Value in CSV: "These are ""quotes"""
What happens is that I will get an extra quote on that value in the database and also any additional lines until it reaches another quote in the CSV. Any ideas on how to solve this?
Hmm. I tried to duplicate this problem but can't. Where does my data differ from yours? Can you provide sample data to duplicate this? Here's what I did:
> cat /tmp/data.csv
"aaaa","bbb ""ccc"" ddd",xxx
xxx,yyy,"zzz ""ooo"""
foo,bar,baz
mysql> CREATE TABLE t2 (a varchar(20), b varchar(20), c varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql> LOAD DATA INFILE '/tmp/data.csv' INTO TABLE t2 FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' (a, b, c);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from t2;
+------+---------------+-----------+
| a | b | c |
+------+---------------+-----------+
| aaaa | bbb "ccc" ddd | xxx |
| xxx | yyy | zzz "ooo" |
| foo | bar | baz |
+------+---------------+-----------+
3 rows in set (0.00 sec)
Looks ok to me(?)
Also note that if you're working on a Windows platform you might need to use
LINES TERMINATED BY '\r\n' instead.