Inches quotes and spaces making troubles inside MySQL - php

I have a long list of electrical equipment with a column for details where it contain information for each electrical component. (About 1k of rows).
So for LG, I have a detail like: LG SCREEN 40''
Now I have this query inisde my PHP page:
$type = $_REQUEST['type'];
$details = $_REQUEST['details'];
$quantity = $_REQUEST['quantity'];
$price = $_REQUEST['price'];
$update = "SELECT * FROM purchases
WHERE sale_type = :type AND sale_details LIKE %:details%";
$prepUpd = $conn->prepare($update);
$prepUpd->bindValue(':type', $type);
$prepUpd->bindValue(':details', $details);
$prepUpdExec = $prepUpd->execute();
$result = $prepUpd->fetchAll();
The reason that I added LIKE %:details% is because my client added some data using multiple space so I have some variables like that: LG LED 32'' (I DON'T KNOW EVEN WHY HE DID THIS) and this space make errors when I want to select this type of details.
So the use of % gives me this error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '%'LED SAMSUNG 40\'\'''
And I think that the inches '' in database is making some trouble when selecting and updating, so any help is appreciated.
And is their any way to remove the extra space inside each cell? And how to solve the problem of inches quote '', and of course the error about like % :...

1. Using like
You have to add the % to the value being queried, not to your sql statement.
$details = '%' . $_REQUEST['details'] .'%';
$update = "SELECT * FROM purchases WHERE sale_type = :type AND sale_details LIKE :details";
$prepUpd = $conn->prepare($update);
2. Removing spaces
Best solution is to "normalize" your type column. Substitute any sequence of spaces by a single space. This should be done when storing the data in your table. If there are no multiple spaces everything will become muchg easier.
Edit 1:
If you want to sanitize your data manually you can use the following sql command
update purchases set sale_type = replace(sale_type,' ',' ');
Repeat this multiple times until no more rows are affected by the query.
Probably you don't like to do that... So let's look at the alternatives.
MySql offers replace() and trim()for string substitution and removal of leading/trailing spaces.
trim() example:
select trim(' XXX '); # result 'XXX'
This is a good result and will be useful but now comes the problem...
replace() example
# Replace two spaces by one space
select replace(' XXX ',' ',' '); # result' XXX '
As you can see this will indeed replace two spaces with one space but the result may be somehow surprising. The output string will still have multiple spaces.
It may be tempting to use multiple replace() calls to get better results:
# replace three spaces by one space, than replace two spaces by one space
select replace(replace(' XXX ',' ',' '),' ',' '); # result: ' XXX '
Still one space left :-(
You can use as many replace() inside replace() you will never get a solution which works in each and every case.
Conlusion: This may work in many situations but it will not work in all situations.
If you want to apply replace() to your code nevertheless then try it like this:
$update = "SELECT * FROM purchases
WHERE replace(sale_type,' ',' ') = replace(:type,' ',' ') AND sale_details LIKE %:details%";
Edit 2
You could switch from = to like
// Replace each sequence of spaces with "% %"
$type = preg_replace('/\s+/','% %',$type);
$update = "SELECT * FROM purchases WHERE sale_type like :type AND sale_details LIKE %:details%";
3. And how to solve the problem of inches quote ''
I really believe you have no problem with quotes. When using prepared statement care is taken to escape those characters.

Related

SQLSRV Update Query to remove spaces

Using a combination of MS-SQL, PHP, and JSON, I have a column in my page called VendorAddress that outputs to the browser like this:
1111 THAT WAY DRIVE �TORRANCE
That strange black diamond with the questionmark.
I have narrowed it down to the fact that some users are copying and pasting from Excel, and there is an extra space between the street and city. I can prevent this from happening in the future. It's the ones that already been saved to the table that is causing a problem for me.
I have found there are over 300 records in the MS-SQL database that have this extra space.
What I need to do is write a query that would update the column by removing this extra space.
UPDATE [main].[dbo].[suppliers] SET [VendorAddress] = '1111 THAT WAY DRIVE TORRANCE' WHERE [PartnerCode] = '00011144';
This is the query I was using, going record for record for each PartnerCode that has the black diamond (336 total). I refuse to go record for record on this. I need to write a query that will do it for me.
I am not sure how to go about doing this. Everything I find online tells me to use TRIM, but it's only for trailing spaces. These are not trailing spaces. They are within the string.
I wish to write a query that would look at the whole table and remove the unnecessary spaces from within the string.
Edit
The special character cannot be seen in the database itself. The only time you see it is when PHP outputs it to the browser.
Basically, within the table, the field contains an extra space. The black diamond cannot be seen within the table.
It seems like you should be able to just employe the REPLACE function:
UPDATE [main].[dbo].[suppliers]
SET [VendorAddress] = REPLACE(VendorAddress, '�', '')
This command seems to work:
SELECT REPLACE('1111 THAT WAY DRIVE �TORRANCE', '�', '')
Have you tried updating it away? Here's some code for capturing the glyph if copy/paste won't work.
DECLARE #Glyph CHAR(1);
SELECT #Glyph = SUBSTRING([VendorAddress]
, -- Put numberic position of Glyph in string here
,1)
FROM [main].[dbo].[suppliers]
WHERE [PartnerCode] = '00011144'; -- Record with erroneous Glyph
SELECT #Glyph AS [Questionable Character]
, [VendorAddress] AS [Before]
, REPLACE([VendorAddress],#Glyph,'') AS [After]
WHERE [PartnerCode] = '00011144'; -- Use same record as above.
/* Uncomment out this bit when you know it works...
UPDATE [main].[dbo].[suppliers]
SET [VendorAddress] = REPLACE([VendorAddress],#Glyph,'')
WHERE [VendorAddress] LIKE '%' + #Glyph + '%';
*/
To replace double spaces with a single space use the following:
UPDATE [main].[dbo].[suppliers]
SET [VendorAddress] = replace([VendorAddress], ' ',' ')
WHERE [VendorAddress] LIKE '% %'
Repeat it until you get 0 rows affected.
* EDIT *
Otherwise can you execute this query to find out the code of that character?
select distinct cast([VendorAddress] AS varbinary) FROM [main].[dbo].[suppliers] WHERE [VendorAddress] LIKE '1111 THAT WAY DRIVE%TORRANCE'

REGEX not working for mysql for replacing comma separated ids

Ok I know my database is not normalized but in my case, It is not possible to normalize the data as each user has different access level with access rights, everytime I modify something and I need to delete the rows and insert back so I went for comma-separated values, here the issue is if I remove a particular group, regex doesn't work, it throws me an error..am using php and the error goes like this
FUNCTION database_name.REGEXP_REPLACE does not exist
Table structure
allowed_group_ids
+----------------+
12345,34345,55454
My query, say for example $delete_id is 12345 or say 55454, I only pass one ID at a time and the id's has no space in between and it's a text field
UPDATE tbl_scripts SET allowed_group_ids = TRIM(BOTH ','
FROM REGEXP_REPLACE(allowed_group_ids, '(,(\s)?)?$detele_id', ''))
WHERE system_id = {$_SESSION['system_id']}
So what's wrong in here?
There is no such thing as regexp_replace in MySQL.
You could perform this query using regular replace:
UPDATE tbl_scripts SET allowed_group_ids =
trim(BOTH ',' FROM
replace(
replace(allowed_group_ids, '$delete_id',','),
',,',
','
)
)
WHERE system_id = {$_SESSION['system_id']}
This first removes the ID, and removes any doubled-up commas, then removes any commas at the start/end of the string. This should be sufficient but you can add another replace to remove whitespace if necessary.
Update: SQL Fiddle shows the query in action

MySQL SELECT statement using PHP GET variable

I have a PHP script that is generating a MySQL select statement:
select * from words where word = 'Classic'
There is exactly one word in the words table with the variable word equal to Classic.
When my PHP page executes, I get no results from the query. If I echo the string that is being used to execute the query, cut and paste that into the SQL window in PHPMyAdmin in the database, I also get no results. However, if I re-type that EXACT string into the SQL window in PHPMyAdmin (with the same quote characters), I get the proper result of one row.
The word Classic from the select statement is gotten from a PHP GET (see code below). I can echo the $word variable, and get the correct result of 'Classic'. What am I doing wrong?
Here is my code:
<?php
require ('dbconnect.php');
$word = $_GET["word"];
$selectStr = "SELECT * FROM words WHERE word = '" . $word . "'";
if ($results = MySQL($dbName, $selectStr))
{
$rowCount = MySQL_NUMROWS($results);
}
$resultRow = MYSQL_FETCH_ROW($results);
$wordID = $resultRow[0];
?>
Please, please, please sanitize that word. mysql_real_escape_string() should do the trick.
$selectStr = "SELECT * FROM words WHERE word LIKE '" . $sanitized_word_i_promise . "'"; should work :)
Just to explain: "=" should work for exact matches. This includes uppercase / lowercase, spaces etc. You should probably trim that result first too, before using it in the query.
If you have foo stored in the database (note the space at the end) - it won't match foo, without a space. You'll want to use LIKE 'foo%' - probably.
Either way, Sourabh is right, although performance wise, this isn't a big hit when trying to match exact strings, you should look for the problem in other places first (such as, is the item in the database an exact match?).
First off you should not take any user input and directly input it into a query without sanitizing it, or using a prepared statement.
Now that we've gotten that out of the way: have you tried doing a strcmp() with the variable and your string written in? Such as
echo strcmp($_GET['word'], "Classic")
If you get a result other than 0 it means they are not the same, most likely there will be a whitespace of some sort in the $_GET variable. use trim() on it to take out whitespace. Also could be a case sensitivity issue as well.

Issues with inserting special characters CodeIgniter

I am trying to insert a mysql query itself into a table field(Executing a series of queries when certain conditions met), but whenever there is any special characters in query, it is converted in to its corresponding entities.
For example, if Iam inserting this query to table, the quote will become " '" , > to > and space to &# . Is there any way to insert the query as it is and display in correct form .
"select
case item_id
when 206 then '1 Column'
when 255 then '2 Columns'
end as split,
# case oi.product_id
# when 24 then 'XXXX'
# when 28 then 'CCCC'
# when 30 then 'EEEE'
# else 'Something Else'
# end as product,
case oi.price_id
when 72 then 'UYT - Single Pay'
when 73 then 'UYT - Single Pay'
when 74 then 'UYT - Single Pay'
else 'Upsell'
end as product,
count(distinct(al.cust_id)) as the_count
from logtable al
where item_id in (206,255) and
activity_dts > '2012-01-31 19:15:00' and
o.order_is_refunded = 0 and
t.response_code = 1 and
t.response_reasontext not like '%testmode%'
group by 1,2;"
Please give me suggestions or Am I missing any thing here. The charset used by my CI installation is UTF-8.
There shouldn't be any problem with inserting your string, as it IS a string, and the database library doesn't make any character encoding by itself, afaik. What encoding are the database and the tables? (the connection should be UTF-8, as per default settings)
Since you're using the framework, you can use its methods (and not mysql_real_escape_string() or, god, addslashes()!! like suggested in other answers).This should work:
$string_query = "select
case item_id
when 206 then '1 Column'
when 255 then '2 Columns'....";
$sql = "INSERT INTO table(column) VALUES (?)";
$this->db->query($sql, array($string_query));
The query bindings automatically escapes FOR SQL, so for that you're safe (you could have used ActiveRecord with the same result). I don't know what couldn't be working in this, surely NO FUNCTIONS encodes html.
Maybe you're doing the encoding somewhere else: are you sure you're not calling xss_clean(), htmlspecialchars()/htmlentities(), or you have XSS protection enabled, or you pass TRUE as second paramenter of $this->input-> ?
If all the above for some reason - for wich you didn't provide enought information - fails, you can alwasy encode everything:
$string_query = base64_encode("select.....");
// HERE YOU MAKE THE INSERT QUERY
and when you retrieve it, you base64_decode() the string. But the ideal solution is not this, it should work without flaws anyway.
PHP addshlashes
This function will help you add the query along with its quotes as it is, in your db.
Also you can do this way,
If your queries just have multiple single quotes only, then border it by double quotes:
like $tmp = "See single' quotes";
or vice-versa like:
$tmp = 'See double " quotes';
Try following
$data_insert = mysql_real_escape_string($values);
Also you can find it in detail http://php.net/manual/en/function.mysql-real-escape-string.php

MySQL select from char column using int - leading zero causes unexpected result

I have the following data:
stockcode (CHAR) | description (VARCHAR)
----------------------------------------------
1234 | some product
01234 | some other product
I run the following code:
$sql = "SELECT * FROM stock WHERE stockcode = " . $db->quoteSmart($stockcode)
$res = $db->query($sql);
If I pass the stock code "01234" in, I get the second row as expected. If I pass in "1234" I get both rows, when I expect to only get the first.
By echoing out the sql statements, it seems to be because only the 01234 stockcode gets quotes around it, the 1234 one doesn't (presumably quoteSmart thinks as it is an integer it doesn't need quoting?).
Mysql is then comparing the int 1234 to the CHAR column, and deciding they both match (presumably it is doing the comparison as ints?)
There are a lot of places in the code which build queries like this, and 99% of the time, the stockcode variable will be alphanumeric, it's only occasionaly entirely numeric, and very rarely contains a leading zero, this is just a fluke occurrence I stumbled across today.
Can anyone recomend an easy solution?
Try explicitly casting your variables to strings:
$db->quoteSmart((string)$stockcode);
// instead of:
// $db->quoteSmart($stockcode);
Edit:
If this does not work, I imagine that quoteSmart() isn't really that smart (or it's trying to be too smart for it's own good), so you'll very likely need to stop using it and stick to bound parameters (which I suggest over this method anyway).
Add quotes so the char in the database don't get converted to numbers for the comparison
$sql = "SELECT * FROM stock
WHERE stockcode = '" . $db->quoteSmart($stockcode). "'"
2nd Version:
$stockcode_str = $db->quoteSmart($stockcode);
if (is_numeric($stockcode_str))
$stockcode_str = "'$stockcode_str'";
$sql = "SELECT * FROM stock
WHERE stockcode = $stockcode_str";

Categories