MySQL bug? Select WHERE id='1blah' - mysql

MySQL Version 5.0.67
Take a look at this very simple table and tell me if I have found a MySQL bug, I have tried to search for an answer but as you can imagine it's a bit hard to come up with the right search terms
CREATE TABLE `product` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(60) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `product` VALUES (1, 'jim');
INSERT INTO `product` VALUES (2, 'bob');
From there I can then select the following
SELECT * FROM `product` WHERE `id` = '1';
Obviously this returns a row, but then, so does this
SELECT * FROM `product` WHERE `id` = '1blah';
Erm... WHY? Surely this is wrong or am I going mad? Will crawl the web a bit more before I file a bug report with MySQL.

It's automatically converting the string "1blah" into an integer. As the string begins with a "1" the resultant integer is simply 1.
As such, it's just trying to do the right thing, even though it might seem a bit counter-intuitive.

This happens because of type conversion. Since your column has integer value, '1blah' is converted to 1. Please, see http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html for more details.

If you didn't enclose the integer id in quotes, it'd work and you'd get an error as you'd hope. That is,
SELECT * FROM `product` WHERE `id` = 1;
1 row in set
works, while
SELECT * FROM `product` WHERE `id` = 1blah;
ERROR 1054 (42S22): Unknown column '1blah' in 'where clause'
errors.

Related

While Insert Records To MySQL, get in Error Code 1054

I'm new to MySQL & I try to enter records to mysql table. I'm getting following error
INSERT INTO advertising.discountauthorizationrequst SET DARDateTime=cast('2003-01-13 16:50:32' as datetime), `DARPubCode`=trim('DD'), `DARPubDate`=cast('2022-05-08' as date), `DARAutUser`=trim("U0001"), `DARDeviceID`=trim('123456789ABCDEFGHIJKL987456'), `DARMessage`=trim("This Is Test Message"), `DARGranted`=("0"), `DARUser`=trim("DATAENTRYUSERNAME") Error Code: 1054. Unknown column 'DARDateTime' in 'field list'
I listed my INSERT statement below. Someone please help me to solve this issue. I'm using mysql workbench 8.0.
Columns:
DARDateTime datetime PK
DARPubCode varchar(3) PK
DARPubDate date PK
DARAutUser varchar(5)
DARDeviceID varchar(50)
DARMessage varchar(100)
DARGranted varchar(1)
DARUser varchar(50) PK
Here is script
INSERT INTO `advertising`.`discountauthorizationrequst`
SET
`DARDateTime`=cast('2003-01-13 16:50:32' as datetime),
`DARPubCode`=trim('DD'),
`DARPubDate`=cast('2022-05-08' as date),
`DARAutUser`=trim("U0001"),
`DARDeviceID`=trim('123456789ABCDEFGHIJKL987456'),
`DARMessage`=trim("This Is Test Message"),
`DARGranted`=("0"),
`DARUser`=trim("DATAENTRYUSERNAME");
Edited..
Table Inspactor - DDL
CREATE TABLE `discountauthorizationrequst` (
`DARDateTime` datetime NOT NULL,
`DARPubCode` varchar(3) NOT NULL,
`DARPubDate` date NOT NULL,
`DARAutUser` varchar(5) DEFAULT NULL,
`DARDeviceID` varchar(50) DEFAULT NULL,
`DARMessage` varchar(100) DEFAULT NULL,
`DARGranted` varchar(1) DEFAULT NULL,
`DARUser` varchar(50) NOT NULL,
PRIMARY KEY (`DARDateTime`,`DARPubCode`,`DARPubDate`,`DARUser`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
You are actually confusing the SQL commands and coming up with a hybrid of them. The INSERT command most commonly is done in two ways..
insert into SomeTable
( these, columns )
values
( oneValue, anotherValue)
or
insert into SomeTable( these, columns )
select oneColumn, secondColumn
from SomeOtherTable
where SomeCondition
The UPDATE command is based on an EXISTING record that you want to change
Update SomeTable set
thisColumn = SomeValue,
anotherColumn = SomeOtherValue
where SomeCondition
So, what you appear to be doing would be written as
INSERT INTO advertising.discountauthorizationrequst
( DARDateTime,
DARPubCode,
DARPubDate,
DARAutUser,
DARDeviceID,
DARMessage,
DARGranted,
DARUser
)
values
(
cast('2003-01-13 16:50:32' as datetime),
'DD',
'2022-05-08',
'U0001',
'123456789ABCDEFGHIJKL987456',
'This Is Test Message',
'0',
'DATAENTRYUSERNAME'
)
Notice the readability with formatting, you can see each column that is needed followed by the explicit values (which could be parameterized during code later) are in the same ordinal context. So, if you ever needed to add a new column to the insert, easy to do with the same ordinal position in the values provided secondarily to it.
As for the 3rd column, by providing a string in YYYY-MM-DD, SQL typically auto-converts to a date format. Other fields, you dont need to explicitly TRIM() everything. If parameterized, you would pass the trimmed VALUE, when you get to that point in your development.
I found the mistake that I made. I created triggers for the above table. After I deleted those triggers its working.

Why does MySql update ignore where clause?

I'd like to find all rows of a table with unformatted text in a specific column and re-format it. Update seems like the right choice for this but it fails. For example this table:
CREATE TABLE `test` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `test` (name) VALUES ('jerk'),('cad'),('slouch'),('slime');
Running the following update to add an ! to each name that doesn't contain it (but not names that do) ignores the where clause and always updates:
UPDATE test SET name = CONCAT(name, '!') WHERE LOCATE(name, '!') = 0;
Repeated application of this update keeps adding more ! to the end of name.
What's going on here and how can I do this conditional update?
EDIT: fixed typo WHERELOCATE -> WHERE LOCATE
It looks like your arguments for LOCATE are backwards. It's LOCATE(substr, str).
http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_locate

SELECT query returns no result without ORDER BY clause

I have this query:
SELECT `Stocks`.`id` AS `Stocks.id` , `Locations`.`id` AS `Locations.id`
FROM `rowiusnew`.`c_stocks` AS `Stocks`
LEFT JOIN `rowiusnew`.`g_locations` AS `Locations` ON ( `Locations`.`ref_id` = `Stocks`.`id` AND `Locations`.`ref_type` = 'stock' )
GROUP BY `Stocks`.`id`
HAVING `Locations.id` IS NOT NULL
This returns 0 results.
When I add
ORDER BY Locations.id
to the exactly same query, I correctly get 3 results.
Noteworthy: When I discard the GROUP BY clause, I get the same 3 results. The grouping is necessary for the complete query with additional joins; this is the simplified one to demonstrate the problem.
My question is: Why do I not get a result with the original query?
Note that there are two conditions in the JOIN ON clause. Changing or removing the braces or changing the order of these conditions does not change the outcome.
Usually, you would suspect that the field id in g_locations is sometimes NULL, thus the ORDER BY clause makes the correct referenced result be displayed "at the top" of the group dataset. This is not the case; the id field is correctly set up as a primary key field and uses auto_increment.
The EXPLAIN statement shows that filesort is used instead of the index in those cases when I actually get a result. The original query looks like this:
The modified, working query looks like this:
Below is the table definitions:
CREATE TABLE IF NOT EXISTS `c_stocks` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_stock_type` int(10) unsigned DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`locality` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `StockType_idx` (`id_stock_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `g_locations` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`ref_type` enum('stock','object','branch') DEFAULT NULL,
`ref_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UniqueLocation` (`ref_type`,`ref_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The ref_id field features a long comment that I omitted in this definition.
After being unable to reproduce the error on SQLFiddle.com and also on my second computer, I realized that there must be a bug involved.
Indeed, my used version 5.6.12 suffers from this bug:
Some LEFT JOIN queries with GROUP BY could return incorrect results. (Bug #68897, Bug #16620047)
See the change log of MySQL 5.6.13: http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-13.html
An upgrade to 5.6.17 solved my problem. I am not getting the results I expect, independent of ORDER clauses and aggregate functions.
Remove
having locations.id is not null
instead use
where locations.id is not null
locations.id is not null is not a problem for the grouping - you don't want them included at all.
Also, you need to do something with the locations.id since it isn't in the group by clause. Do you want "max" locations.id?
so your query now becomes:
SELECT `Stocks`.`id` AS `Stocks.id` , max(`Locations`.`id`) AS `Locations.id`
FROM `rowiusnew`.`c_stocks` AS `Stocks`
LEFT JOIN `rowiusnew`.`g_locations` AS `Locations` ON ( `Locations`.`ref_id` = `Stocks`.`id` AND `Locations`.`ref_type` = 'stock' )
WHERE `Locations.id` IS NOT NULL
GROUP BY `Stocks`.`id`
Make those changes and it should work better for you.
FYI: I think that by putting in the order by clause, you are allowing the engine to guess what you want for the locations.id, otherwise it has no clue. In something other than MYSQL, it wouldn't run at all.

mysql insert find next in sequence

Sorry, this one is hard to explain in the title.
I have a simple table like this:
CREATE TABLE `categories` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(125) NOT NULL,
`desc` text NOT NULL,
`ordering` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
The ordering column is normally set in the client-- that is, the client can drag and reorder these categories, so it is not auto_incremented.
My question is, when I want to insert a row outside the client using a direct SQL insert is there a way to quickly get the max of the ordering column in the same statement?
Something like:
INSERT INTO `categories` (title, desc, ordering)
VALUES ('test title', 'description', (SELECT max(ordering) FROM `categories`)+1);
I've tried a dozen variations on this theme with no success.
The trick to get that to work is to avoid using the VALUES clause, and instead use a SELECT as the rowsource for the INSERT,
something like this:
INSERT INTO `categories` (title, desc, ordering)
SELECT 'test title', 'description', MAX(ordering)+1 FROM `categories`
NOTE: This may work with MyISAM tables, which disallows concurrent inserts. But for other engines that allow concurrent INSERTS, this approach will likely be "broken by design". I don't think there is any guarantee that two INSERT statements running concurrently won't generate the same value for the ordering column.
This design is also "broken by design" when the categories table is empty, because MAX(ordering) would return a NULL. But an IFNULL function can fix that.
SELECT 'test title', 'description', IFNULL(MAX(ordering),0)+1 FROM `categories`
try this:
insert into `categories` (`title`, `desc`, `ordering`)
select 'test title','description', max(ordering) + 1 FROM `categories`

Select From Where Not Exists query

Memberships table:
CREATE TABLE `Consultant_Memberships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`membership_url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
Memberships_List table:
CREATE TABLE `Consultant_Memberships_List` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`consultant_id` int(11) DEFAULT NULL,
`membership_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Within the Memberships table, there is a list of 'Societies' which the member can become a part of. On selection, this is then added to the 'Memberships_List' in the form of:
id - Auto increment
consultant_id - The unique ID of the user who's added the societies
membership_id - Refers to the 'id' from the memberships table.
I want to be able to show in a drop down list only the memberships which the user hasn't chosen yet. So far I've got:
$query = $db->query("SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title` `FROM `Consultant_Memberships
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)");
I'm currently getting this error, and also unsure if this is the correct query:
PHP Fatal error: Uncaught exception 'PDOException' with message '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 'WHERE `Consultant_Memberships_List`.`id` = )' at line 1' in /Users/Sites/pages/medical.php:72
Stack trace:
#0 /Users/Sites/pages/medical.php(72): PDO->query('SELECT `Consult...')
#1 /Users/Sites/index.php(18): include('/Users/Site...')
#2 {main}
thrown in /Users/Sites/pages/medical.php on line 72
FROM is missing in the NOT EXISTS subquery.
SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title` `FROM `Consultant_Memberships
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)
you have a wrong syntax try something like this i am not writing exect query but checked in sql fiddle and thats wrond
SELECT Consultant_Memberships.id, Consultant_Memberships.title FROM Consultant_Memberships
WHERE NOT EXISTS (SELECT Consultant_Memberships.id, Consultant_Memberships.title from Consultant_Memberships
WHERE Consultant_Memberships.id = 1)
Always watch to the left from the highlighted query part. WHERE in your case
SELECT `Consultant_Memberships.`id`, `Consultant_Memberships`.`title`
`FROM <--- extra backtick
`Consultant_Memberships <--- unclosed backtick
by the way, do not overuse backticks. most of your fields require them not
...and you have your query totally screwed as it seems
As far as I understood your question, it have to be
SELECT cm.id, title
FROM Consultant_Memberships cm LEFT JOIN Consultant_Memberships_List
ON cm.id=membership_id WHERE membership_id IS NULL
Please note that your question has nothing to do with PDO.
it's clear SQL query question.
Kindly try this one:
SELECT a.id, a.title
FROM Consultant_Memberships a, Consultant_Memberships_List b
WHERE a.id <> b.consultant_id
The reason you are getting syntax error because if you see your subquery you will find out that you are not specifying any table in it.
WHERE NOT EXISTS (SELECT `Consultant_Memberships`.`id`, `Consultant_Memberships`.`title`
WHERE `Consultant_Memberships`.`id` = $user_id)
If you need more help, please let us know...
Regards...
Mr.777