A PDO prepared update statement is somehow updating the datetime column for the selected record in the table, even though that particular datetime column is not even in the query.
if(isset($_POST['editCriteria']))
{
$value = $_POST['editCriteria'];
$editusername = $value['editusername'];
$hiddenUsername = $value['hiddenUsername'];
$editfullname = $value['editfullname'];
$editemail = $value['editemail'];
$edituserlevel = $value['edituserlevel'];
$editdivision = $value['editdivision'];
$editdept = $value['editdept'];
$editphone = $value['editphone'];
try
{
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$update = $dbc->prepare("UPDATE users_edi SET username = :uname,
fullname = :fname, userlevel = :ulevel, email = :uemail,
division = :udivision, dept = :udept, phone = :uphone WHERE username = :hname");
$update->execute([
'uname' => $editusername,
'fname' => $editfullname,
'ulevel' => $edituserlevel,
'uemail' => $editemail,
'udivision' => $editdivision,
'udept' => $editdept,
'uphone' => $editphone,
'hname' => $hiddenUsername
]);
if($update)
{
echo "Success: User has been updated.";
}
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
}
In the database table, there is a column called lastLoginDate that is being updated to the current datetime.
If you'll notice in the update statement above, the query does not include lastLoginDate.
How is lastLoginDate being updated when it's not even in the query?
Upon using the SHOW CREATE TABLE command, there was indeed a trigger on the lastLoginDate column.
CREATE TABLE `users_edi` (
`username` varchar(30) NOT NULL DEFAULT '',
`fullname` varchar(50) DEFAULT NULL,
`userlevel` tinyint(1) unsigned NOT NULL,
`ipaddress` varchar(30) DEFAULT NULL,
`email` varchar(150) DEFAULT NULL,
`entrydate` datetime DEFAULT NULL,
`division` varchar(35) DEFAULT NULL,
`password` varchar(32) DEFAULT NULL,
`userid` varchar(32) DEFAULT NULL,
`timestamp` int(11) unsigned NOT NULL,
`job_title` varchar(30) DEFAULT NULL,
`dept` varchar(50) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
`lastLoginDate` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, // <-- here
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I will have to ask another question on how to remove this trigger.
Related
I use Codeigniter 3.1.11 and have some code which makes one big query to MySQL with an array. The time of a query with a limit of 30000 is about 9 seconds.
How can I reduce the request time? Maybe by using some indexes on my table, or do you know another method? If I need to use indexes, what indexes would I need to use and how can I use these indexes in my query on Codeigniter?
Code from model:
function rows_update() {
$query = $this->db->order_by('rating', 'DESC')->get_where('members', 'game_rating_and_balance_update_last_time <= now() - INTERVAL 1 DAY', '30000', '0');
$arrUpdateBatchData = [];
while ($row = $query->unbuffered_row('array'))
{
// some code here
$arrUpdateData = [
'UserID' => $row['UserID'],
'game_vault_balance' => $new_game_vault_balance,
'game_available_balance' => $new_game_available_balance,
'rating' => $rating_member,
'game_rating_and_balance_update_last_time' => date('Y-m-d H:i:s')
];
$arrUpdateBatchData[] = $arrUpdateData;
if (count($arrUpdateBatchData) > 500)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
}
//update last items
if (count($arrUpdateBatchData) > 0)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
return;
}
Raw query to MySQL with update_batch (I simply write only one row from an array):
UPDATE members SET game_vault_balance = CASE WHEN UserID = '9915075' THEN 803.60516004772 ELSE game_vault_balance END, game_available_balance = CASE WHEN UserID = '9915075' THEN 4.1253850908788 ELSE game_available_balance END, rating = CASE WHEN UserID = '9915075' THEN 0.24 ELSE rating END, game_rating_and_balance_update_last_time = CASE WHEN UserID = '9915075' THEN '2020-07-24 22:00:36' ELSE game_rating_and_balance_update_last_time END WHERE UserID IN('9915075')
Table structure:
CREATE TABLE `members` (
`id` int(10) UNSIGNED NOT NULL,
`UserID` varchar(64) NOT NULL,
`telegram_id` varchar(64) DEFAULT NULL,
`first_name` varchar(64) DEFAULT NULL,
`last_name` varchar(64) DEFAULT NULL,
`language` varchar(64) DEFAULT NULL,
`currency` varchar(64) DEFAULT NULL,
`status` varchar(64) DEFAULT NULL,
`rating` varchar(64) DEFAULT NULL,
`game_vault_balance` decimal(32,8) DEFAULT 0.00000000,
`game_available_balance` decimal(32,8) DEFAULT 0.00000000,
`game_rating_and_balance_update_last_time` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
`created` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Indexes of this table:
ALTER TABLE `members`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `UserID` (`UserID`) USING BTREE;
AUTO_INCREMENT for the members table:
ALTER TABLE `members`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;
I have this function which inserts to my database some values. Values are inserted just fine but i am trying to insert them in upper case which doesn't work. If i use print_r after the for loop values are printed in uppercase. But in my database it is not stored as uppercase. Has anyone experienced an issue like this before?
function tryToInsertRow($mCurrentRowData){
global $connection;
// Make Data Uppercase
for($i = 0; $i < sizeof($mCurrentRowData); $i++){
$mCurrentRowData[$i] = strtoupper($mCurrentRowData[$i]);
}
$query_insert = "INSERT INTO main_db (contact_id, customer_code, customer_name, territory, firstname, lastname, contact_type_description, contact_is_primary, mailing_street, mailing_postal_code, mailing_city, mailing_country, email, mobile_phone, phone) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
if ($stmt = mysqli_prepare($connection, $query_insert)) {
// bind parameters for markers
if (!mysqli_stmt_bind_param($stmt, "sssssssdsssssss", $mCurrentRowData[0] ,$mCurrentRowData[1] ,$mCurrentRowData[2] ,$mCurrentRowData[3] , $mCurrentRowData[4] ,$mCurrentRowData[5] ,$mCurrentRowData[6] ,$mCurrentRowData[7] ,$mCurrentRowData[8] ,$mCurrentRowData[9] ,$mCurrentRowData[10] ,$mCurrentRowData[11] ,$mCurrentRowData[12] ,$mCurrentRowData[13] ,$mCurrentRowData[14])) {
error_log(mysqli_error($connection));
return false;
}
//execute query
if (!mysqli_stmt_execute($stmt)) {
error_log(mysqli_error($connection));
return false;
}
mysqli_stmt_close($stmt);
return true;
} else {
error_log(mysqli_error($connection));
return false;
}
}
Main db creation :
CREATE TABLE `main_db` (
`contact_id` varchar(255) NOT NULL,
`customer_code` varchar(255) NOT NULL,
`customer_name` varchar(255) DEFAULT NULL,
`territory` varchar(255) DEFAULT NULL,
`firstname` varchar(255) DEFAULT NULL,
`lastname` varchar(255) DEFAULT NULL,
`contact_type_description` varchar(255) DEFAULT NULL,
`contact_is_primary` int(1) DEFAULT NULL,
`mailing_street` varchar(255) DEFAULT NULL,
`mailing_postal_code` varchar(255) DEFAULT NULL,
`mailing_city` varchar(255) DEFAULT NULL,
`mailing_country` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`mobile_phone` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
`is_processed` int(1) NOT NULL DEFAULT '0',
UNIQUE KEY `contact_id` (`contact_id`,`customer_code`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
So I'm running a PDO update working, and for some reason it won't update the table...
$business_id = 9874128;
$hidden = 1;
$query = "UPDATE business_property_overrides SET hidden=? WHERE business_id=?";
try {
$stmt = $pdo->prepare($query);
$stmt->execute(array($business_id, $hidden));
}
For some reason this won't update, even though I get no errors. The existing tables schema looks like this, and the data is:
There is an existing data set with business_id = 9874128 and hidden set to 0, but it won't update when I run the above code.
CREATE TABLE `business_property_overrides` (
`business_id` int(11) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(512) NOT NULL,
`apt_type` varchar(25) DEFAULT NULL,
`apt_num` varchar(9) DEFAULT NULL,
`street_address` varchar(255) DEFAULT NULL,
`city` varchar(255) DEFAULT NULL,
`state` varchar(255) DEFAULT NULL,
`zip` varchar(25) DEFAULT NULL,
`phone` varchar(11) DEFAULT NULL,
`url` varchar(512) DEFAULT NULL,
`hours` varchar(100) DEFAULT NULL,
`openhours` varchar(100) DEFAULT NULL,
`location` point DEFAULT NULL,
`yelp` varchar(512) DEFAULT '0',
`twitter` varchar(512) DEFAULT '0',
`hidden` tinyint(1) DEFAULT '0',
`merged` int(11) DEFAULT NULL,
`closed` tinyint(1) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `business_id` (`business_id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9874134 DEFAULT CHARSET=utf8;
The hidden is TINYINT 1 characters long, you are assigning it business_id which is 7 characters long, that is the error.
Change
$stmt->execute(array($business_id, $hidden));
To:
$stmt->execute(array($hidden,$business_id))
As I've already commented over here, or you can simply use the placeholders of taking no care about the occurence like as
$query = "UPDATE business_property_overrides SET hidden = :hidden WHERE business_id = :business_id";
try {
$stmt = $pdo->prepare($query);
$stmt->execute(array(":business_id" => $business_id, ":hidden" => $hidden));
}
The following code returns 0 instead of the biggest number from the row order_id
if ($result_oid = $link->prepare("SELECT MAX(order_id) AS order_id FROM $table")) {
$result_oid->execute();
$obj = $result_oid->get_result()->fetch_object();
$oid_o = $obj->id;
$result_oid->close();
$oid = $oid_o + 1;
}
Here is a working example using the PHP mysql instead of mysqli (with the same mysql database):
mysql_connect($host, $user, $pwd) or die ("Couldn't connect to MySQL database.");
mysql_select_db($db) or die ("No Database found!");
$query = mysql_query('SELECT MAX(order_id) FROM airsale_list');
$result = mysql_fetch_array($query, MYSQL_NUM);
$max_order_id = $result[0];
$max_order_id = (int)$max_order_id;
$oid = $max_order_id++;
echo "<h4>order_id: $oid</h4>";
mysql_close();
Table structure
CREATE TABLE IF NOT EXISTS `airsale_list` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cat` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`desc_small` varchar(1000) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`lastupdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`price` int(20) NOT NULL,
`currency` varchar(3) NOT NULL DEFAULT 'EUR',
`total_time` varchar(255) DEFAULT NULL,
`engine` varchar(1000) DEFAULT NULL,
`engine_time` varchar(255) DEFAULT NULL,
`prop` varchar(1000) DEFAULT NULL,
`prop_time` varchar(255) DEFAULT NULL,
`exterior` varchar(2000) DEFAULT NULL,
`interior` varchar(2000) DEFAULT NULL,
`avionics` varchar(5000) DEFAULT NULL,
`add_info` varchar(5000) DEFAULT NULL,
`order_id` int(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=103;
I think you should be using $obj->order_id instead of $obj->id since you are grabbing the maximum value as order_id in the query.
if ($result_oid = $link->prepare("SELECT MAX(order_id) AS order_id FROM $table")) {
$result_oid->execute();
$obj = $result_oid->get_result()->fetch_object();
$oid_o = $obj->order_id;
$result_oid->close();
$oid = $oid_o + 1;
}
I restarted the MySQL service and I attempted to use my PHP programs delete function to delete an existing row but I'm finding although the delete queries were counted the row was not deleted. I tried applying on delete cascade to the foreign key of the child table but that did not seem to have an effect. I'm wondering why the delete would be doing nothing.
CREATE TABLE `customers` (
`idcustomers` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(45) DEFAULT NULL,
`lastname` varchar(45) DEFAULT NULL,
`address1` varchar(45) DEFAULT NULL,
`address2` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
`zip` varchar(45) DEFAULT NULL,
`phone` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`cell` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idcustomers`),
UNIQUE KEY `idcustomers_UNIQUE` (`idcustomers`)
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=latin1
CREATE TABLE `events` (
`idevents` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(250) DEFAULT NULL,
`start` datetime DEFAULT NULL,
`end` datetime DEFAULT NULL,
`allday` varchar(50) DEFAULT NULL,
`url` varchar(1000) DEFAULT NULL,
`customerid` int(11) NOT NULL,
`memo` longtext,
`dispatchstatus` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idevents`),
KEY `FK_events` (`customerid`),
CONSTRAINT `FK_events` FOREIGN KEY (`customerid`) REFERENCES `customers` (`idcustomers`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1
Com_delete 2
The PHP looks like this:
<?php
session_start();
date_default_timezone_set("America/Los_Angeles");
if($_SESSION['loggedin'] != TRUE)
{
header("Location: index.php");
}
require_once('../php.securelogin/include.securelogin.php');
$mysqli = new mysqli($ad_host, $ad_user, $ad_password, "samedaycrm");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$customerid = $_SESSION['customer_id'];
$tSQL = "delete from events where customerid = \"$customerid\"";
$result = $mysqli->query($tSQL);
$tSQL = "delete from customers where idcustomers = \"$customerid\"";
$result = $mysqli->query($tSQL);
echo $mysqli->error;
?>
Assuming that the customerid and idcustomers columns are both numeric it should be fine. You should not need to quote the variables in those queries btw, then you wouldnt need to escape them. You may try:
$tSQL = "delete from events where customerid = $customerid";
but it should not be any different than what you used already. Of course if you are not sure of the type of the column you can use:
$tSQL = "delete from events where customerid = '".$customerid."'";
or you can get away with:
$tSQL = "delete from events where customerid = '$customerid'";
but I have always hated that for some reason.
if all of that fails troubleshoot by spitting out the $customerid (or even the whole $tSQL) variable and then trying the query manually in phpmyadmin or toad or whatever db client you use, and see what it tells you. If it just says 0 rows affected, then run it like a select instead. Tailor to fit.