I know this is very silly question. But I am disappointed with the behaviour of this query. I am updating Customers in Opencart. When I have written and executed an Update query, few fields are being inserted and few are not. Especially I need to update 'status' and 'approved' columns. Please check the below Query.
UPDATE oc_customer SET customer_group_id=1,store_id=0,firstname='',lastname='HEATHER HUME',telephone='9876543210',fax='0',password='f53cbb1352950831a84035d320063383f345cfce',salt='rCF2EquoV',status='1',approved='1',date_added='2016-08-31',discount=62.00 WHERE customer_id='1418'
Please let me know what is wrong with this. It is updating Telephone column and not status,approved.
Below is the structure of my table
CREATE TABLE IF NOT EXISTS `oc_customer` (
`customer_id` int(11) NOT NULL,
`customer_group_id` int(11) NOT NULL,
`store_id` int(11) NOT NULL DEFAULT '0',
`firstname` varchar(32) NOT NULL,
`lastname` varchar(32) NOT NULL,
`email` varchar(96) NOT NULL,
`telephone` varchar(32) NOT NULL,
`cellphone` varchar(32) NOT NULL,
`fax` varchar(32) NOT NULL,
`password` varchar(40) NOT NULL,
`salt` varchar(9) NOT NULL,
`cart` text,
`wishlist` text,
`newsletter` tinyint(1) NOT NULL DEFAULT '0',
`address_id` int(11) NOT NULL DEFAULT '0',
`custom_field` text NOT NULL,
`ip` varchar(40) NOT NULL,
`status` tinyint(1) NOT NULL,
`approved` tinyint(1) NOT NULL,
`safe` tinyint(1) NOT NULL,
`token` text NOT NULL,
`date_added` datetime NOT NULL,
`discount` decimal(8,2) NOT NULL DEFAULT '0.00',
`tax_id` varchar(50) NOT NULL,
`subscribe` varchar(5) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=1419 DEFAULT CHARSET=utf8;
My php code is
$query = "UPDATE oc_customer SET customer_group_id=1,store_id=0,firstname='$first_name',lastname='$last_name',telephone='$phone',fax='$fax',password='$password',salt='$salt',status=".(int)$status.",approved=".(int)$approved.",date_added='$date_added1',discount=$discount WHERE customer_id='$customer_id' ";
mysqli_query($con,$query);
$con is my connection variable.No problem with that.
PHP doesn't always play nice when you try to cast variables in string concatenation. You're also treating an integer as a string for customer_id.
Try this:
$query = "UPDATE oc_customer SET customer_group_id=1,store_id=0,firstname='$first_name',lastname='$last_name',telephone='$phone',fax='$fax',password='$password',salt='$salt',status=".((int)$status).",approved=".((int)$approved).",date_added='$date_added1',discount=$discount WHERE customer_id=$customer_id ";
As a side note, it's very bad security practice to inject variables into an SQL query like that. You should use parameters to avoid SQL injection attacks.
I run your code and found nothing wrong, my row was updated successfully with status and approved both fields.
but I will suggest you not to typecast your variables to integer because when you are typecasting them to integer at the same time you are concatenating them to a string which finally resulting in a string only so no need to typecast only make sure that you provide valid values to those variables through PHP, try following statement and revert if problem solved.
$query = "UPDATE oc_customer SET customer_group_id=1,store_id=0,firstname='$first_name',lastname='$last_name',telephone='$phone',fax='$fax',password='$password',salt='$salt',status=$status,approved=$approved,date_added='$date_added1',discount=$discount WHERE customer_id='$customer_id'";
Thanks for your response. There is no problem with the query. The problem is with special characters which we can't see either in our editors or in PhpMyAdmin. This may be helpful for someone who have stuck with same problem, i.e., Query executes in PhpMyAdmin and not in PHP Script.
Please type the query on your own. Please don't copy and paste it from anywhere. Not atleast from your own page again.
Please type everything on your own because copy paste may again copy the invisible special characters into query which again makes your query tough to debug.
Related
I have this query in PHP which I call from an Android app.
$sql = "SELECT
`asset`.`idasset`,
`asset`.`idlocation`,
`asset`.`asset_barcode`,
`asset`.`asset_number`,
`asset`.`category_name`,
`asset`.`make`,
`asset`.`model`,
`asset`.`serial_number`,
`asset`.`iduser`,
`asset`.`idcost_centre`,
`asset`.`idcondition`,
`asset`.`idstatus`,
`asset`.`latitude`,
`asset`.`longitude`,
`asset`.`asset_description`
from `asset`";
This is the response I receive from the call in Android Studio console:
D/RAW RESPONSE: Notice: Unknown column 'asset.idlocation' in 'field list'
But that field does exist.
Here's the full create statement I reverse copied to clipboard in MySQLWorkbench.
CREATE TABLE `asset` (
`idasset` int(11) NOT NULL AUTO_INCREMENT,
`idlocation` int(11) NOT NULL,
`asset_barcode` varchar(50) DEFAULT NULL,
`asset_number` varchar(50) DEFAULT NULL,
`category_name` varchar(50) DEFAULT NULL,
`asset_description` varchar(250) DEFAULT NULL,
`make` varchar(50) DEFAULT NULL,
`model` varchar(50) DEFAULT NULL,
`serial_number` varchar(255) DEFAULT NULL,
`iduser` int(11) DEFAULT NULL,
`idcost_centre` int(11) DEFAULT NULL,
`idcondition` int(11) DEFAULT NULL,
`idstatus` int(11) DEFAULT NULL,
`longitude` varchar(45) DEFAULT NULL,
`latitude` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idasset`),
KEY `cost_center_fk_idx` (`idcost_centre`),
KEY `iduser_fk_idx` (`iduser`),
KEY `category_name_fk_idx` (`category_name`),
CONSTRAINT `category_name_fk` FOREIGN KEY (`category_name`) REFERENCES `category` (`category_name`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `iduser_fk` FOREIGN KEY (`iduser`) REFERENCES `user` (`iduser`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=93 DEFAULT CHARSET=utf8;
If I run that exact raw query in PHPMyAdmin or MySQLWorkbench it works, but not in PHP.
If I swap around the sequence of the fields I also get the same error with:
`asset`.`asset_description`
`asset`.`latitude`,
`asset`.`longitude`,
But all the other fields are fine.
Strange thing is this query worked a few weeks ago.
Am I missing something?
I don't have any ideas.
Starting to think its a PHP or MySQL setup or something.
Any help would be greatly appreciated as time is not on my side.
Sorry silly mistake, I did point to another DB.
I am trying to write insert a row into a database with a column that is a composite of other columns to help with searching. Here is my PHP code:
$compose=$house." ".$street." ".$district." ".$posttown." ".$county." ".$postcode;
$sql=sprintf("INSERT INTO Address (House,Street,District,PostTown,County,PostCode,Active,Composite) VALUES ('%s','%s','%s','%s','%s','%s',%s,'%s')",
$house,
$street,
$district,
$posttown,
$county,
$postcode,
$binactive,
$compose);
(I know I should be using prepared statements, that is part of the next refactoring)
The statement executes without errors but the Composite column is being evaluated as a number. That is, if $house starts with a number that number is inserted, if $house is a name then 0 is inserted.
$compose is being concatenated properly.
The column is definitely a varchar. Here is the table create script:
CREATE TABLE `Address` (
`idAddress` int(11) NOT NULL AUTO_INCREMENT,
`House` varchar(45) NOT NULL,
`Street` varchar(45) NOT NULL,
`District` varchar(45) DEFAULT NULL,
`PostTown` varchar(45) NOT NULL,
`County` varchar(45) NOT NULL,
`PostCode` varchar(45) NOT NULL,
`Composite` varchar(1000) NOT NULL,
`Active` binary(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`idAddress`),
UNIQUE KEY `idAddress_UNIQUE` (`idAddress`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=latin1;
So...where am I going wrong?
i don't know what i am doing wrong here but i have been trying to get this to work for hours. i just want it to create a table that doesn't exist. i made it as simple as i can make it and still it just returns false and doesn't change anything. please let me what i am doing wrong thank you in advance.
$conn=mysql_connect('localhost:3306', 'root', '');
mysql_select_db("test",$conn);
$sql = "CREATE TABLE IF NOT EXISTS 'works' (
`autoPlace` int(11) unsigned NOT NULL auto_increment,
`element` float(255) NOT NULL,
`month` tinyint(4) NOT NULL ,
`mday` tinyint(4) NOT NULL ,
`wday` char(12) NOT NULL ,
`time` smallint(6) NOT NULL,
PRIMARY KEY (`autoPlace`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8";
$thisKeepsReturningFalse= mysql_query($sql);
var_dump($thisKeepsReturningFalse);
When I tried to execute your query I got this error:
Incorrect column specifier for column 'element'
The problem is float(255) is not a valid declaration
It needs to be float(x) where x<=53, or you can use float(x,y) - see mysql docs here
Also, as pointed out in the comments, you have single quotes around works. Remove them or replace them with backticks.
After fixing these errors, I was able to successfully execute your query.
"CREATE" command in MySQL is not return value command so that it always return false(not like SELECT). To check if the command "CREATE" success or not, you can use "SHOW TABLES" to check after executing the "CREATE" command.
When you create a float element you must specify the decimals with a comma.And also the name of the table can't be with this format '' it must to be inside ``.
So in this example the query should be :
CREATE TABLE IF NOT EXISTS `works`
(
`autoPlace` int(11) unsigned NOT NULL auto_increment,
`element` float(255,0) NOT NULL,
`month` tinyint(4) NOT NULL ,
`mday` tinyint(4) NOT NULL ,
`wday` char(12) NOT NULL ,
`time` smallint(6) NOT NULL,
PRIMARY KEY (`autoPlace`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
Note how the float it's float(255,0) and not just 255. You must set this , 0 is the default
I use the following prepared statement:
SELECT *
FROM
c_members,c_users,c_positions,c_done_meetings
WHERE
c_positions.POS_ID=c_users.POS_ID
AND c_members.CLUB_ID = ?
AND USER_POINTS >= ?
AND USER_POINTS <= ?
AND c_users.POS_ID LIKE ?
AND MEM_ACADEMY LIKE ?
AND MEM_SEX LIKE ?
AND MEM_GRADELVL LIKE ?
AND MEM_GPA >= ?
AND MEM_GPA <= ?
AND MEM_ARCHIVE = 0
GROUP BY
c_members.MEM_ID, c_members.CLUB_ID
HAVING
SUM(c_done_meetings.MEDONE_ATTEND = 'u') >= 1
ORDER BY
USER_POINTS DESC
However this query takes 21.971405982971 seconds to load 111 records. When I remove "Having SUM(...)" clause, the performance is 100% better. Is there a way I could optimize it better?
Edit: (Table structures)
CREATE TABLE IF NOT EXISTS `c_done_meetings` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`MEETING_ID` int(11) NOT NULL,
`MEDONE_ATTEND` varchar(1) NOT NULL COMMENT 'E=excused, U=unexcused, P=present',
UNIQUE KEY `unique` (`MEM_ID`,`CLUB_ID`,`MEETING_ID`),
KEY `MEETING_ID` (`MEETING_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `c_members` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`MEM_FIRST` varchar(50) NOT NULL,
`MEM_MIDDLE` varchar(50) DEFAULT NULL,
`MEM_LAST` varchar(50) NOT NULL,
`MEM_SEX` tinyint(1) NOT NULL COMMENT '0-Male 1-Female',
`MEM_EMAIL` varchar(100) DEFAULT NULL,
`MEM_GRADELVL` int(11) NOT NULL,
`MEM_ACADEMY` varchar(50) DEFAULT '',
`MEM_GPA` double DEFAULT '0',
`MEM_ADDRESS` varchar(500) DEFAULT NULL,
`MEM_CITY` varchar(100) DEFAULT NULL,
`MEM_STATE` varchar(100) DEFAULT NULL,
`MEM_ZIP` int(11) DEFAULT NULL,
`MEM_TELEPHONE` varchar(25) DEFAULT NULL,
`MEM_AP` tinyint(1) NOT NULL,
`MEM_HONORS` tinyint(1) NOT NULL,
`MEM_ESOL` tinyint(1) NOT NULL,
`MEM_HISP` tinyint(1) NOT NULL,
`MEM_WHITE` tinyint(1) NOT NULL,
`MEM_MULTI` tinyint(1) NOT NULL,
`MEM_NATIVE` tinyint(1) NOT NULL,
`MEM_BLACK` tinyint(1) NOT NULL,
`MEM_ASIAN` tinyint(1) NOT NULL,
`MEM_EXTRA` varchar(10000) DEFAULT NULL,
`MEM_ARCHIVE` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `MEM_ID` (`MEM_ID`,`CLUB_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `c_positions` (
`POS_ID` int(11) NOT NULL AUTO_INCREMENT,
`CLUB_ID` int(11) NOT NULL,
`POS_NAME` varchar(20) NOT NULL,
`POS_DESC` varchar(500) NOT NULL,
`POS_ADMIN` tinyint(1) NOT NULL,
`POS_ATN_VIEW` tinyint(1) NOT NULL,
`POS_ATN_CHKIN` tinyint(1) NOT NULL,
`POS_ATN_FINALIZE` tinyint(1) NOT NULL,
`POS_MEM_VIEW` tinyint(1) NOT NULL,
`POS_MEM_ADD` tinyint(1) NOT NULL,
`POS_MEM_EDIT` tinyint(1) NOT NULL,
`POS_POS_VIEW` tinyint(1) NOT NULL,
`POS_POS_ADD` tinyint(1) NOT NULL,
`POS_POS_EDIT` tinyint(1) NOT NULL,
`POS_MEET_VIEW` tinyint(1) NOT NULL,
`POS_MEET_ADD` tinyint(1) NOT NULL,
`POS_MEET_EDIT` tinyint(1) NOT NULL,
`POS_EVENT_VIEW` tinyint(1) NOT NULL,
`POS_EVENT_ADD` tinyint(1) NOT NULL,
`POS_EVENT_EDIT` tinyint(1) NOT NULL,
`POS_EVENT_UPDATE` tinyint(1) NOT NULL,
`POS_REPORT_VIEW` tinyint(1) NOT NULL,
`POS_ARCHIVE_VIEW` tinyint(1) NOT NULL,
`POS_ANNOUNCEMENTS` tinyint(1) NOT NULL,
`POS_WEB_CUSTOM` tinyint(1) NOT NULL,
PRIMARY KEY (`POS_ID`),
UNIQUE KEY `UNIQUE_NAME` (`CLUB_ID`,`POS_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
CREATE TABLE IF NOT EXISTS `c_users` (
`MEM_ID` int(11) NOT NULL,
`CLUB_ID` int(11) NOT NULL,
`USER_PIN` int(11) NOT NULL,
`USER_POINTS` double NOT NULL,
`POS_ID` int(11) NOT NULL,
`USER_ARCHIVE` tinyint(1) NOT NULL DEFAULT '0',
UNIQUE KEY `MEM_ID` (`MEM_ID`,`CLUB_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Edit 2:
Yes all ids are indexed, the SUM(...) >= # calculates the number of missed meetings. # is a parameter set by the user (I just hard coded a 1 for testing)
You need to have indexes an all fields used in the WHERE clause, on all fields on which the tables are joined (you need to explicitly state your join conditions as right now, you are getting a Cartesian join), on all fields used for grouping and all fields used for sorting.
The last problem is the HAVING clause there. You are not going to be able to use an index at all for that since it is a calculated value. If this is a query you will use often in the system (i.e. not just for reporting), you might consider adding a field you can use as a flag for this filtering purpose. Whenever you set c_done_meetings.MEDONE_ATTEND = 'u' in any of your queries, you could also set this flag for the member or user or whatever this is associated with so that you have an easy field to filter on in a WHERE clause.
Outside of that, you might actually gain better performance by getting a reduced list of users or members with that value of u in a subselect and then join using that subselect as a table.
EDIT:
After seeing your actual table structure, I can clearly see where you need to add indexes. I am also wondering why you have tables c_users and c_members with the same exact primary key. Why would these not just be a single table?
Some things that pop out at me:
You use like quite a lot. Try to do something with your php code so that this isn't necessary. For example, mem_sex has a limited number of choices. Make the front end a radio button or dropdown so you send a value where you can use = instead of like.
Two, if you add a sum() to the select clause, and the appropriate group by clause, it should run faster. It's worth a shot.
You can denormalise you tables and add field to c_members that represent your
SUM(c_done_meetings.MEDONE_ATTEND = 'u') >= 1
But you need to update that field always, when updating c_done_meetings (can be done with trigger)
Also try to avoid LIKE conditions. Use = insead (it is possible at least for SEX)
I'm working on a codeigniter project and I'm trying to troubleshoot a sql issue. I have a query that updates a date field in my table and it's not updating it at all.
I have this table
CREATE TABLE `Customer` (
`customer_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(55) NOT NULL DEFAULT '',
`last_name` varchar(55) NOT NULL DEFAULT '',
`city` varchar(255) DEFAULT '',
`state` char(2) DEFAULT '',
`zip` int(5) DEFAULT NULL,
`title` varchar(255) NOT NULL DEFAULT '',
`image` varchar(255) DEFAULT '',
`blurb` blob,
`end_date` date DEFAULT NULL,
`goal` int(11) DEFAULT NULL,
`paypal_acct_num` int(11) DEFAULT NULL,
`progress_bar` enum('full','half','none') DEFAULT NULL,
`page_views` int(11) NOT NULL DEFAULT '0',
`total_pages` int(11) NOT NULL DEFAULT '0',
`total_conversions` int(11) NOT NULL DEFAULT '0',
`total_given` int(11) NOT NULL DEFAULT '0',
`conversion_percentage` int(11) NOT NULL DEFAULT '0',
`avg_contribution` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`customer_id`)
) ENGINE=MyISAM AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
and when I run this query to insert data, it runs fine and sets the date to 2012-11-01
INSERT INTO `Customer` (`first_name`, `last_name`, `end_date`) VALUES ('John', 'Smith2', '2012-11-01');
Then I get the customer_id and try to run this query
UPDATE `Customer` SET `end_date` = '2012-14-01' WHERE `customer_id` = '18';
and it sets the date end_date field to 0000-00-00.
Why is it changing the end date to 0000-00-00 rather than 2012-14-01?
2012-14-01 is first day of fourteenth month :)
(so its invalid date, thus casted to 0000-00-00 and Data truncated for column 'end_date' at row 1 warning was returned by mysql, which you can see by querying SHOW WARNINGS to mysql immediately after badly behaving query)
2012-01-14 is 14th of January.
use this:
UPDATE `Customer` SET `end_date` = date('Y-m-d') WHERE `customer_id` = '18';
Use date function to update this field.