How to escape single quotes in MySQL - mysql

How do I insert a value in MySQL that consist of single or double quotes. i.e
This is Ashok's Pen.
The single quote will create problems. There might be other escape characters.
How do you insert the data properly?

Put quite simply:
SELECT 'This is Ashok''s Pen.';
So inside the string, replace each single quote with two of them.
Or:
SELECT 'This is Ashok\'s Pen.'
Escape it =)

' is the escape character. So your string should be:
This is Ashok''s Pen
If you are using some front-end code, you need to do a string replace before sending the data to the stored procedure.
For example, in C# you can do
value = value.Replace("'", "''");
and then pass value to the stored procedure.

See my answer to "How to escape characters in MySQL"
Whatever library you are using to talk to MySQL will have an escaping function built in, e.g. in PHP you could use mysqli_real_escape_string or PDO::quote

Use this code:
<?php
$var = "This is Ashok's Pen.";
mysql_real_escape_string($var);
?>
This will solve your problem, because the database can't detect the special characters of a string.

If you use prepared statements, the driver will handle any escaping. For example (Java):
Connection conn = DriverManager.getConnection(driverUrl);
conn.setAutoCommit(false);
PreparedStatement prepped = conn.prepareStatement("INSERT INTO tbl(fileinfo) VALUES(?)");
String line = null;
while ((line = br.readLine()) != null) {
prepped.setString(1, line);
prepped.executeQuery();
}
conn.commit();
conn.close();

There is another way to do this which may or may not be safer, depending upon your perspective. It requires MySQL 5.6 or later because of the use of a specific string function: FROM_BASE64.
Let's say you have this message you'd like to insert:
"Ah," Nearly Headless Nick waved an elegant hand, "a matter of no importance. . . . It's not as though I really wanted to join. . . . Thought I'd apply, but apparently I 'don't fulfill requirements' -"
That quote has a bunch of single- and double-quotes and would be a real pain to insert into MySQL. If you are inserting that from a program, it's easy to escape the quotes, etc. But, if you have to put that into a SQL script, you'll have to edit the text (to escape the quotes) which could be error prone or sensitive to word-wrapping, etc.
Instead, you can Base64-encode the text, so you have a "clean" string:
SWtGb0xDSWdUbVZoY214NUlFaGxZV1JzWlhOeklFNXBZMnNnZD
JGMlpXUWdZVzRnWld4bFoyRnVkQ0JvWVc1a0xDQWlZU0J0WVhS
MFpYCklnYjJZZ2JtOGdhVzF3YjNKMFlXNWpaUzRnTGlBdUlDNG
dTWFFuY3lCdWIzUWdZWE1nZEdodmRXZG9JRWtnY21WaGJHeDVJ
SGRoYm5SbApaQ0IwYnlCcWIybHVMaUF1SUM0Z0xpQlVhRzkxWj
JoMElFa25aQ0JoY0hCc2VTd2dZblYwSUdGd2NHRnlaVzUwYkhr
Z1NTQW5aRzl1SjMKUWdablZzWm1sc2JDQnlaWEYxYVhKbGJXVn
VkSE1uSUMwaUlBPT0K
Some notes about Base64-encoding:
Base64-encoding is a binary encoding, so you'd better make sure that you get your character set correct when you do the encoding, because MySQL is going to decode the Base64-encoded string into bytes and then interpret those. Be sure base64 and MySQL agree on what the character encoding is (I recommend UTF-8).
I've wrapped the string to 50 columns for readability on Stack Overflow. You can wrap it to any number of columns you want (or not wrap at all) and it will still work.
Now, to load this into MySQL:
INSERT INTO my_table (text) VALUES (FROM_BASE64('
SWtGb0xDSWdUbVZoY214NUlFaGxZV1JzWlhOeklFNXBZMnNnZD
JGMlpXUWdZVzRnWld4bFoyRnVkQ0JvWVc1a0xDQWlZU0J0WVhS
MFpYCklnYjJZZ2JtOGdhVzF3YjNKMFlXNWpaUzRnTGlBdUlDNG
dTWFFuY3lCdWIzUWdZWE1nZEdodmRXZG9JRWtnY21WaGJHeDVJ
SGRoYm5SbApaQ0IwYnlCcWIybHVMaUF1SUM0Z0xpQlVhRzkxWj
JoMElFa25aQ0JoY0hCc2VTd2dZblYwSUdGd2NHRnlaVzUwYkhr
Z1NTQW5aRzl1SjMKUWdablZzWm1sc2JDQnlaWEYxYVhKbGJXVn
VkSE1uSUMwaUlBPT0K
'));
This will insert without any complaints, and you didn't have to manually-escape any text inside the string.

You should escape the special characters using the \ character.
This is Ashok's Pen.
Becomes:
This is Ashok\'s Pen.

If you want to keep (') apostrophe in the database use this below code:
$new_value = str_replace("'","\'", $value);
$new_value can store in database.

You can use this code,
<?php
$var = "This is Ashok's Pen.";
addslashes($var);
?>
if mysqli_real_escape_string() does not work.

In PHP, use mysqli_real_escape_string.
Example from the PHP Manual:
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
mysqli_query($link, "CREATE TEMPORARY TABLE myCity LIKE City");
$city = "'s Hertogenbosch";
/* this query will fail, cause we didn't escape $city */
if (!mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
printf("Error: %s\n", mysqli_sqlstate($link));
}
$city = mysqli_real_escape_string($link, $city);
/* this query with escaped $city will work */
if (mysqli_query($link, "INSERT into myCity (Name) VALUES ('$city')")) {
printf("%d Row inserted.\n", mysqli_affected_rows($link));
}
mysqli_close($link);
?>

$var = mysqli_real_escape_string($conn, $_POST['varfield']);

If you are using PHP, just use the addslashes() function.
PHP Manual addslashes

For programmatic access, you can use placeholders to automatically escape unsafe characters for you.
In Perl DBI, for example, you can use:
my $string = "This is Ashok's pen";
$dbh->do("insert into my_table(my_string) values(?)",undef,($string));

Use either addslahes() or mysql_real_escape_string().

The way I do, by using Delphi:
TheString to "escape":
TheString=" bla bla bla 'em some more apo:S 'em and so on ";
Solution:
StringReplace(TheString, #39,'\'+#39, [rfReplaceAll, rfIgnoreCase]);
Result:
TheString=" bla bla bla \'em some more apo:S \'em and so on ";
This function will replace all Char(39) with "\'" allowing you to insert or update text fields in MySQL without any problem.
Similar functions are found in all programming languages!

Maybe you could take a look at function QUOTE in the MySQL manual.

This is how my data as API response looks like, which I want to store in the MYSQL database. It contains Quotes, HTML Code , etc.
Example:-
{
rewardName: "Cabela's eGiftCard $25.00",
shortDescription: '<p>adidas gift cards can be redeemed in over 150 adidas Sport Performance, adidas Originals, or adidas Outlet stores in the US, as well as online at adidas.com.</p>
terms: '<p>adidas Gift Cards may be redeemed for merchandise on adidas.com and in adidas Sport Performance, adidas Originals, and adidas Outlet stores in the United States.'
}
SOLUTION
CREATE TABLE `brand` (
`reward_name` varchar(2048),
`short_description` varchar(2048),
`terms` varchar(2048),
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
While inserting , In followed JSON.stringify()
let brandDetails= {
rewardName: JSON.stringify(obj.rewardName),
shortDescription: JSON.stringify(obj.shortDescription),
term: JSON.stringify(obj.term),
}
Above is the JSON object and below is the SQL Query that insert data into MySQL.
let query = `INSERT INTO brand (reward_name, short_description, terms)
VALUES (${brandDetails.rewardName},
(${brandDetails.shortDescription}, ${brandDetails.terms})`;
Its worked....
If nothing works try this :
var res = str.replace(/'/g, "\\'");
var res = res.replace(/"/g, "\\\"");
It adds the \ escape character to all(every) occurrences of ' and "
Not sure if its the correct/professional way to fix the issue
I'm guessing it will work but in actual content, every single and double quotes will be replaced with \ character

As a Python user I replace the quote with a raw "'":
don_not_work_str = "This is Ashok's Pen."
work_str = don_not_work_str.replace("'", r"\'")

For Python,I tried many ways to escape '"', not work, cuz I have various input.
Finally, I just use these code, the data in database was same like the input.
tmp = val.replace('\\', r'\\')
ret = tmp.replace('"', r'\"')

Related

Insert into table SET - rows with special characters skipped

I have this query:
$sql = "
INSERT INTO table SET
name = '$name',
sku = '$number',
description = '$desc'
";
But the rows containing some special characters (in my case this ') are not inserted.. How I can solve?
Thanks in advance.
When you construct your query, you need to escape the data you are inserting.
You need to at least use addslashes() function in PHP, like this:
$sql = "INSERT INTO table SET name = '".addslashes($name)."', sku = '".addslashes($number)."', description = '".addslashes($desc)."'";
However more correct way is to use a different function than addslashes, which would properly handle all characters in the data, not only apostrophes.
I am using my custom 'escape' function like this:
function escape($text)
{
return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $text);
}
So using this function, you would write:
$sql = "INSERT INTO table SET name = '".escape($name)."', sku = '".escape($number)."', description = '".escape($desc)."'";
You must use parameterised queries instead of manually appending those values. Currently if name, number or description would contain any sql it would get executed.
A lot more detailed answer is in How can I prevent SQL injection in PHP?
Read about escaping characters in mysql. I think it is done with \

MySQL: SQL to insert rows using a string of ids

I need to insert ~150 simple rows (an id, and a static status of 'discard'). I have a string of the ids:
'123', '234r', '345', '456xyz'...
What's the simplest way to insert rows using this string of ids?
It seems like maybe there's some way to split the string on commas and... create a temp table to ...? I don't know - it just seems like this is the kind of thing that MySQL often manages to pull off in some cool, expedient way.
An example how to do create an INSERT statement with a few lines of PHP:
<?php
// copy your string of ids into this variable
$input = "'123', '234r', '345', '456xyz'";
// modify next line to get your desired filename
$filename = 'insert.sql'
// modify next line to your table name
$insert_statement = "INSERT INTO your_table_name (id, status) VALUES \n" .
'(' . implode(", 'discard')\n(", explode(', ', $input)) . ", 'discard');\n";
file_put_contents($filename, $insert_statement);
?>
Note
This is for this special use case. If the string of ids contains some special characters like single quotes, then this simple approach will fail.
The one way is to create CSV file with appropriate records and upload it at once to mysql.
Please follow this tutorial: http://www.mysqltutorial.org/import-csv-file-mysql-table/

MYSQL?PHP using variables to replace filenames in insert statements

I have a page that inserts records into a database file called ports that holds two fields, called id and port.
The data is checked by an include, checkform.php, that strips out any bad data and blank entries.
It works fine, and as I have more data files of a similar construction it seems logical to use the same page for inserting records by passing the file and field names to the page as parameters.
The SQL that is used for the stand alone page is:
$sql='INSERT IGNORE INTO ports(port) VALUES(?)';
I want to do some thing like:
$sql='INSERT IGNORE INTO $filename ($fieldname) VALUES(?)';
I have looked on the forum and found many solutions that do not appear to work
Like :
$sql='INSERT IGNORE INTO '$filename' ('$fieldname') VALUES(?)';
$sql='INSERT IGNORE INTO "'$filename'" ("'$fieldname'") VALUES(?)';
$sql='INSERT IGNORE INTO `$filename` (`$fieldname`) VALUES(?)';
as well as :
$sql="INSERT IGNORE INTO `$filename` (`$fieldname`) VALUES (`$fieldname`);";
and many others. The combination seems endless, and so far I would have been better just copying the pages and changing the variables by hand. The code for the insert is below:
// check if form submitted and has a value
If (isset($_POST['insert']))
{ require('../includes/checkform.inc.php');
// continue if the field is OK
if (empty($missing)) // ** missing is empty if the data is clean and exists
{ // process the input.
require_once('../includes/connection.inc.php');
// initialize a flag
$OK = false;
//create database connection
$conn = mysqli_connect( $DatabaseServer,$DatabaseUser, $DatabasePassword, $DatabaseName);
// Initialize prepared statement
$stmt = $conn->stmt_init();
//create SQL
$sql='INSERT IGNORE INTO ports(port) VALUES(?)'; //#
//bind parameters and execute statement
if($stmt->prepare($sql)) {
$stmt->bind_param('s',$_POST['port']);//#
$stmt->execute();
if ($stmt->affected_rows > 0)
$OK = true;
}//if $tmt
}// if empty
// redirect if successful or display an error - on page below
if ($OK) {
header('Location:insertok.php');
exit;
} else {
$error = htmlspecialchars($stmt->error);
The lines with //# against them are the ones that I need help with.
Most of the code is modified from a book by David Powers.
Howard Walker
To interpolate variables in a string, you have to use double quotes "$var". Note that you shouldn't surround $var with single quotes. And your table and column names might be one of the reserved words. It complains when that happens. You use backticks to escape the reserved words.
$sql="INSERT IGNORE INTO `$filename` (`$fieldname`) VALUES (?);";
This should work just fine.
EDIT
Your file/field might also include the characters that mySQL doesn't like. In that case, escape the query string before executing it. Refer: http://us3.php.net/manual/en/mysqli.real-escape-string.php
$sql = $stmt->real_escape_string($sql);

PHP force a var to have a certain type

This may be a stupid question but I might aswell as it :)
is there away to force
$tel1 = '05';// string
settype($tel1,'string');
$tel1 = 06;//either throw error, or convert it to string automatically.
var_dump($tel1);//(string [2]) 05
The above code is of the top of my head so might not be accurate but I need to keep a variable as a string not numeric, because of some silly thing I have done, now my phone numbers lose the leading 0s :-(
n I cn't rewrite it because it will mess up with other numeric types,b4 u ask it was an automated service for db to check if it was a numeric value or not,
UPDATE
This is the problem
function escape($str){
if(is_numeric($str)){
return $str;
}else{
return "'".mysql_real_escape_string($str).'\'';
}
}
$tel1 = "06";
$sql = 'SELECT * FROM blabla WHERE id = '.escape($tel1).'';
//above is same as below
$sql = 'SELECT * FROM blabla WHERE id = 06 ';
I can't change anything inside the scape function because other inputes thruout the website are using this function, I dont wanna mess their validations.
Your use of is_numeric tests for numeric content, not an integer type. But then you take a variable called $str which implies you want it to be a string.
Perhaps use:
function escape($val) {
if (is_numeric($val) && !is_string($val)) {
return $val;
}
else{
return "'" . mysql_real_escape_string($val) . '\'';
}
}
Now strings will be escaped and quoted, but not if they contain only numeric content.
you can do something like:
$string = (string) $int;
or use a function
$string = strval($int);
You can't force a variable to a specific type in the global scope.
You can force Arrays and Objects in a function.
function getElementsByClassName(DOMNode $parentElement, Array $classNames) {
...
}
If you pass an object that is not an instantiation of DOMNode (or a subclass), or if you don't pass an Array as the second argument, you'll get an error.
You can of course cast any variable, e.g. (string) $tel1.
You shouldn't be treating phone numbers as Ints anyway, because of leading zeroes and possible parenthesis and dashes. Also, once your telephone number is an Int, it won't know its 0 padding anymore because it will be discarded, so casting it back won't give you the original String.
To cast a variable you can use something like:
$i = 1;
$s = (string) $i;
Depending on the db adaptor you might not be able to detect the type being returned from the database. I believe it's PDO that returns everything (even INT values) as strings.
The number_format() function may be of use to you too.
If you declare a variable as:
$var = 06;
it immediately becomes 6 without leading zero because leading zero when it comes to integers is meaningless and therefore it's cut out.
In other words, your variable has to be created as string, which is what you probably deduced yourself.
Quick fix would be the following: you can add another parameter to your escape() function.
For example:
function escape($str, $force_str = false)
{
if($force_str)
{
// do your conversion, the rest of the site will by default pass false so nothing will be broken
}
}
As alex said, start by making sure the phone number is never converted from string to int in your own code. Then, you need to make sure it will not be converted when sent to your SQL DB.
It ought to work if you do it this way:
$sql = "SELECT * FROM blabla WHERE id = '" . mysql_real_escape_string($tel1) . "'";
This is the same as
$sql = "SELECT * FROM blabla WHERE id = '06'";

How can I insert strings with quotes into Perl DBI queries?

What is the preferred way to insert strings that can contain both single and double quotes (",') into MySql using DBI? For example, $val1 and $val2 can contain quotes:
my $dbh = DBI->connect( ... );
my $sql = "insert into tbl_name(col_one,col_two) values($val1, $val2)";
my $sth = $dbh->prepare($sql);
$sth->execute();
Use a bound query using
$sth = $dbh->prepare("insert into tbl_name(col_one,col_two) values(?,?)");
$sth->execute($val1, $val2);
If you use bound variables, everything is escaped for you.
Update: Changed my example to correspond with the example edited into the question.
Update: I don't know why Adam deleted his answer, but if for some reason you can't use bound variables (aka "placeholders"), you can also use $dbh->quote($var) on the variable. For example:
$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
$dbh->quote(q("Don't"));
Use the quote() method. It will intelligently handle the quoting for you. Example from the docs:
$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
$dbh->quote("Don't");
Slightly modified to have both types of quotes:
$sql = sprintf "SELECT foo FROM bar WHERE baz = %s",
$dbh->quote(q("Don't"));
One small caveat on the bound placeholders, I build a rather large database-loading script that initially used bound placeholders in an older version of Perl/DBI and found what appears to be a memory leak in the placeholder implementation, so if you're looking at using them in a persistent process/daemon or in a high-volume context you may want to make sure process size doesn't become an issue. Switching over to building the query strings using the quote() method eliminated the issue for me.
DBI placeholders are awesome. They shine when you need to execute the same query in a loop. Consider this:
my $dbh = DBI->connect(...);
my $name_pairs = get_csv_data("data.csv");
my $sth = $dbh->prepare("INSERT INTO t1 (first_name, last_name) VALUES (?,?)");
for my $pair (#$name_pairs) {
unless ($sth->execute(#$pair)) {
warn($sth->errstr);
}
}
In this case, having the prepared statement handle is, er, handy.
However, barring this sort of tight-loop cases, I like to see the actual statement that was sent to the server. This is where I lean heavily on quote and frankly sprintf.
# Here, I am confident about the hash keys, less so about the values
$sql = sprintf("INSERT INTO t1 (%s) VALUES (%s)",
join(",", keys(%hash)),
join("," map { $dbh->quote($_) } values(%hash))
);
$sth = $dbh->prepare($sql);
unless ($sth->execute) {
warn($sth->{Statement});
}
Note that you do have to set RaiseError => 0 on $dbh so that you can see the SQL that failed, but this has helped me a great deal in the past.
Cheers.