Mysql query where column_name=a the same as column_name=0? - php

When i am running a query, for example:
"SELECT * FROM program_detaljer where program_ref_id='a'"
All I get from the result is program_ref_id = 0.
Why does this happen, when the program_ref_id column is supposed to be int(11)?

You should read about types conversion in mysql
Before comparison mysql tries to convert string ('a') to number ('0').
mysql> SELECT 0='a';
+-------+
| 0='a' |
+-------+
| 1 |
+-------+
1 row in set, 1 warning (0.00 sec)
You could check value before quering. Or replace = with LIKE : ). (But better to check value type before.)
mysql> SELECT 0 LIKE 'a';
+------------+
| 0 LIKE 'a' |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)

Related

PDO query binding string instead of integer returns results

I have a table with and auto increment id and was just testing a few scenarios when I stumbled across a problem whereby PDO or mysql seems to convert a string to an integer when in an array. Does anyone know why?
If my query is as follows:
$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id");
$check->execute(array(':id'=>1));
it retrieves 1 record - all fine, but if the query uses a string either by design or mistake as follows:
$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id");
$check->execute(array(':id'=>'1 OR id > 0'));
it still retrieves a record with id=1.
Surely nothing should be found? I appreciate I should never allow the 2nd scenario to happen but why is PDO / mysql converting the string to an integer and how is it doing it?
This is a MySQL bug/oversight in string to integer conversion. Instead of raising an error when given an incorrect integer literal, it simply issues a warning.
mysql> select '1'+0;
+-------+
| '1'+0 |
+-------+
| 1 |
+-------+
1 row in set (0,00 sec)
mysql> select '1 hello world'+0;
+-------------------+
| '1 hello world'+0 |
+-------------------+
| 1 |
+-------------------+
1 row in set, 1 warning (0,00 sec)
mysql> show warnings;
+---------+------+---------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '1 hello world' |
+---------+------+---------------------------------------------------+
1 row in set (0,00 sec)
For good or bad, that's how MySQL is designed to behave:
mysql> SELECT CASE
-> WHEN 123='123 pink elephants' THEN 'Equal'
-> ELSE 'Different' END
-> AS 'How are they?';
+---------------+
| How are they? |
+---------------+
| Equal |
+---------------+
1 row in set, 1 warning (0.00 sec)
As you can see, though, it triggers a warning:
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '123 pink elephants' |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)
It's because execute create somthing like: SELECT * FROM tbl_test WHERE id='1 OR id > 0'
$check = $db->prepare("SELECT * FROM tbl_test WHERE id=:id OR id>:id2");
$check->execute(array(':id'=>'1', ':id2' => 0));
or just
$check = $db->prepare("SELECT * FROM tbl_test WHERE id>:id");
$check->execute(array(':id'=>'0'));
With prepared statements and placeholders, the database knows to expect a value that suits the column type. I would expect that it sees your numeric id column and casts the '1 or id > 0' to a number - so you just get the 1.

split MYSQL field into array and search [duplicate]

This question already has answers here:
MySQL query finding values in a comma separated string
(11 answers)
Closed 5 years ago.
I have field in MySQL table. The field is called 'vehicles' When I add vehicles I add them by ID not name, so the field is populated like '2:3:4:6:7:9' 2 will be a car, 7 will be a bike, etc.
What I want to do quickly and simply is when I query the table I want to see if the field vehicle contains '2' is in that field within the 2:3:4:7:9.
I have tried a lot but coming up blank?
Thanks
if you just want to locate any specific number then do like this
$data = "2:3:4:6:7:9";
echo "found on index : " . array_search("2", explode(":", $data));
You can use FIND_IN_SET in quer query like
SELECT *
FROM yourTable
WHERE FIND_IN_SET('2',REPLACE(vehicle ,':',',')) > 0;
samples
mysql> SELECT FIND_IN_SET('1',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 0 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('2',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('7',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 4 |
+------+
1 row in set (0,00 sec)
mysql> SELECT FIND_IN_SET('8',REPLACE('2:3:4:7:9',':',',')) as a;
+------+
| a |
+------+
| 0 |
+------+
1 row in set (0,00 sec)

Big INT in MySql returning a row when the value is set 0 [duplicate]

In my inherited database, sometimes binary questions are encoded as ('Yes', 'No'), and sometimes as (1,0). I mistakenly queried against the string 'Yes' on a field which was numerically encoded. My guess is that the string was turned into a '0' by MySQL.
I have a query like this:
SELECT `children_under_18`
FROM `households`
WHERE `children_under_18` = 'Yes'
GROUP BY `children_under_18`
It ended up only matching records where children_under_18 was 0, the opposite of what I wanted. I know I need to be more careful. I am looking for a definitive answer as to what happened.
String is always converted to 0 when compared to numeric (of course string containing numeric + string is converted numeric. but this is not good practice)
mysql> SELECT 'Yes' + 0;
+-----------+
| 'Yes' + 0 |
+-----------+
| 0 |
+-----------+
1 row in set, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-----------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'Yes' |
+---------+------+-----------------------------------------+
If you want store binary value (Yes/No or True/False) or small value set, ENUM is good choice.
It takes small disk space and can use meaningful String.
mysql> CREATE TABLE enum_test(a ENUM('Yes', 'No'));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into enum_test values('Yes'), ('No'), ('Invalid');
Query OK, 3 rows affected, 1 warning (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 1
mysql> show warnings;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'a' at row 3 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> select * from enum_test where a = 'Yes';
+------+
| a |
+------+
| Yes |
+------+
1 row in set (0.00 sec)
mysql> select * from enum_test where a = 'No';
+------+
| a |
+------+
| No |
+------+
1 row in set (0.00 sec)

mysql - Inserting row in table 1 when specific row deleted on table 2

I decide to insert row in table 1 when specific row deleted on table 2 with trigger mysql get this error :
MySQL said: #1363 - There is no NEW row in on DELETE trigger
How can i do that ?
Consider the following example and change accordingly to your trigger
mysql> create table test (id int, val varchar(20),date datetime);
Query OK, 0 rows affected (0.09 sec)
mysql> insert into test values (1,'aa',now()),(2,'bb',now()),(3,'cc',now());
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> create table test1 like test;
Query OK, 0 rows affected (0.06 sec)
mysql> delimiter //
mysql> create trigger test_del after delete on test
-> for each row
-> begin
-> insert into test1 (id,val,date) values (old.id,old.val,old.date);
-> end ;
-> //
Query OK, 0 rows affected (0.12 sec)
mysql> delimiter ;
mysql> select * from test ;
+------+------+---------------------+
| id | val | date |
+------+------+---------------------+
| 1 | aa | 2014-09-15 15:08:13 |
| 2 | bb | 2014-09-15 15:08:13 |
| 3 | cc | 2014-09-15 15:08:13 |
+------+------+---------------------+
3 rows in set (0.01 sec)
mysql> select * from test1;
Empty set (0.00 sec)
mysql> delete from test where id = 1 ;
Query OK, 1 row affected (0.03 sec)
mysql> select * from test1 ;
+------+------+---------------------+
| id | val | date |
+------+------+---------------------+
| 1 | aa | 2014-09-15 15:08:13 |
+------+------+---------------------+
1 row in set (0.00 sec)

MySql PHP results

Hi i'm working on some code with mysql and need to display the mysql results with php..
MySQL
select distinct(year(Cataloged_Date)) from records;
+------------------------+
| (year(Cataloged_Date)) |
+------------------------+
| 2009 |
+------------------------+
1 row in set (0.00 sec)
PHP
foreach($query->result() as $show){
$data[$i] = $show->Cataloged_Date;
$i++;
}
I'm using codeigniter for the php. Using $show->Cataloged_Date will not return anyting. I'm thinking its $show-> something to display the results...Just cant get it right now...
You need to provide a explicit name or alias for your field in the mysql query - when you apply functions to a column then it's non-obvious what the column name will be.
Try this:
//on MySQL
select distinct(year(Cataloged_Date)) as "Cat_Date" from records;
<?php
foreach($query->result() as $show){
$data[$i] = $show->Cat_Date;
$i++;
}
?>
You can apply an alias to any "value" on your select, be it a column name or the result of a function.
Just do
SELECT something AS YourAlias ...
To give you a clear example:
mysql> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
#A simple value can be given an alias
mysql> select 1 as "Number";
+--------+
| Number |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
mysql> select max(val) from my_values;
+----------+
| max(val) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
#A function
mysql> select max(val) as "max_val" from my_values;
+---------+
| max_val |
+---------+
| 4 |
+---------+
1 row in set (0.00 sec)
#or even a plain column
mysql> select val as "lav" from my_values;
+------+
| lav |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
4 rows in set (0.00 sec)
Yes this is normally true but i'm using Codeigniter php framework. I did get it working with
$query->first_row() as $show
Then just echo $show and the results will display without you needing to know the rows name..

Categories