I'm trying to insert some date to MySQL table with prepared insert with nested 3 nested selects in it. The thing is that for all nested selects a single variable is used. Actual SQL:
INSERT INTO db_test.offers
(`id`,`catalog_service_id`,`offer_name`,
`offer_description`,`offer_url`,
`offer_interaction_format`,`offer_methods`)
VALUES(1,
(SELECT `catalog_service_id` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
(SELECT `catalog_service_name` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
(SELECT `catalog_service_name` FROM db_test.catalog_services
WHERE `catalog_service_code` = ?),
'https://url.com', 'json', 'CC');
PHP code:
class test extends mysqli{
function db_action($host = null){
$mysqli = new mysqli($host, MYSQL_USER, MYSQL_PASS, "db_test");
if(!$mysqli){
die ("couldn't connect to mysql host" . mysqli_connect_error());
}
$codes= ["AAAAA005760000000001","ААААА032680000000001","ААААА032680000000002"];
$query="SQL code from above";
$stmt = $mysqli->prepare($query);
$stmt ->bind_param("sss", $offer, $offer, $offer);
foreach ($codes as $k => $offer) {
if($stmt->execute() === false){
print 'Wrong SQL. Error: ' . $stmt->error . "\r\n";
}else{
$last_inserted_id = $mysqli->insert_id;
print "Insert row with id: " . $last_inserted_id . " for service_code: ". $offer . "\r\n";
}
}
$stmt->close();
}
}
First iteration of foreach works fine (1 row is inserted with correct data), but on 2nd and 3rd (just for an example, real number of elements in $codes array is unknown). The The executed statement on the sql-server is executed with question marks instead of actual value. When I go through the function in debugger - the value of $offer var changes on each iteration of for each.
SQL error that comes from the server is obvious: catalog_service_id cannot be null.
table info:
CREATE TABLE `offers` (
`offer_id` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) NOT NULL,
`catalog_service_id` int(11) NOT NULL,
`offer_name` varchar(255) DEFAULT NULL,
`offer_description` varchar(1000) DEFAULT NULL,
`offer_create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`offer_start_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`offer_stop_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`offer_url` varchar(256) NOT NULL,
`offer_auth` enum('Basic','Digest') DEFAULT NULL,
`offer_auth_name` varchar(255) DEFAULT NULL,
`offer_auth_password` varchar(255) DEFAULT NULL,
`offer_auth_secret` varchar(255) DEFAULT NULL,
`offer_operator_id` int(11) NOT NULL,
`public_offer_url` varchar(1000) NOT NULL,
`offer_interaction_format` enum('urlencoded','json') NOT NULL DEFAULT 'urlencoded',
`offer_methods` enum('CC','MC') NOT NULL DEFAULT 'MC',
`offer_inn` varchar(20) DEFAULT NULL,
`offer_kpp` varchar(20) DEFAULT NULL,
`offer_min` int(11) DEFAULT NULL,
`offer_max` int(11) DEFAULT NULL,
PRIMARY KEY (`offer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
I'm really stuck...
Related
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.
I have a database table with two columns that have been set as boolean. Whenever I store something in the table everything works correctly except the boolean columns are always false. The columns are featured post and published.
I am using php 7.1.1 and MariaDB 10.1.21 on my xampp local installation.
Output of show table:
CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`seo_description` varchar(255) NOT NULL,
`featured_post` tinyint(1) NOT NULL DEFAULT '0',
`published` tinyint(1) NOT NULL DEFAULT '0',
`seo_title` varchar(255) NOT NULL,
`post_type` enum('blog','product') NOT NULL,
`featured_image_id` int(11) NOT NULL,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`),
UNIQUE KEY `seo_title` (`seo_title`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
Php code defining onr of the variables, the other is exactly the same:
if(isset($_POST["published"])){
$published = sanitizeInput($_POST["published"]);
if($published){ //test to see if correct values where being sent and they were
echo json_encode("boolean true");
} else {
echo json_encode("boolean false");
}
} else {
$published = false;
}
$query = "insert into posts "
. "(title, content, seo_description, featured_post, published, seo_title, post_type, category_id) "
. "values "
. "(:title, :content, :seo_description, :featured_post, :published, :seo_title, :post_type, :category_id)";
$stmt = $pdo->prepare($query);
$stmt->bindValue("featured_post", $featuredPost, PDO::PARAM_BOOL);
$stmt->bindValue("published", $published, PDO::PARAM_BOOL);
$stmt->bindValue("title", $title);
$stmt->bindValue("content", $content);
$stmt->bindValue("seo_description", $seoDescription);
$stmt->bindValue("seo_title", $seoTitle);
$stmt->bindValue("post_type", $postType);
$stmt->bindValue("category_id", $categoryId);
$stmt->execute();
Any help would be much appreciated.
Thanks in advance
I have this table:
CREATE TABLE `comment` (
`id` int(11) unsigned NOT NULL,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`comment` text,
`article_id` int(11) unsigned NOT NULL DEFAULT '1',
`date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`deleted` tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
This is in the table:
INSERT INTO `comment` VALUES (0,'Bernard','user#domain.com','This is a comment',1,'2014-07-22 17:34:24',0);
This php code spits out "foo" and nothing else:
<?php
error_reporting(E_ALL);
echo 'foo';
$db = new mysqli("localhost", 'root', '', 'ggs');
$query = $db->prepare("SELECT * FROM `comment` `c` WHERE `c`.`article_id` = ? AND `c`.`deleted` = 0 ORDER BY `c`.`date` ASC");
if (!$query) {
echo $db->errno . " - Could not prepare SQL statement: " . $db->error;
} else {
$query->bind_param('i', 1);
$query->execute();
echo json_encode($query->fetch());
}
echo 'bar';
Why is this failing, and why is it not throwing any errors?
As for the query, you should replace the first 0 a null to let the auto-increment work:
INSERT INTO `comment` VALUES (NULL,'Bernard','user#domain.com','This is a comment',1,'2014-07-22 17:34:24',0);
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 thought I was pretty good at this sort of thing but...
I have the following query from a customer table that is about 8,500 rows and an address table that is about the same number of rows.
This query takes about 10 seconds to complete and I can't figure how to get it to milliseconds.
What am I doing wrong?
<select>
<option value=""></option>
<?php // get the customers
$sql = "
SELECT `cust`.`custid`, `cust`.`custname`, `cust`.`custactive`, `address`.`addtype`, `address`.`address1`, `address`.`addcity`, `address`.`addstate`
FROM `cust`
LEFT Join `address`
ON `cust`.`custid` = `address`.`addcustid`
and `address`.`addtype` = 'b'
WHERE `cust`.`custactive` = 'y'"
;
$result = mysqli_query($con,$sql) or die('Query failed: Could not get list of CLIENTS: ' . mysqli_error($con)); // query
while ($row = mysqli_fetch_array($result)) {
$custid = $row['custid'];
$space="";
$endingspaces = 4-(2*strlen($prodid));
for($count=1; $count<$endingspaces; $count++){
$space .=" ";
}
$custid = $row['custid'];
$custname = substr($row['custname'],0,15);
$address1 = substr($row['address1'],0,15);
$addcity = substr($row['addcity'],0,15);
$addstate = $row['addstate'];
print "<option value=\"$custid\">$custid: $space$custname, $address1, $addcity, $addstate</option>";
}
?>
</select>
DDL:
CREATE TABLE `cust` (
`custid` int(11) DEFAULT NULL,
`custname` varchar(45) DEFAULT NULL,
`custactive` varchar(255) DEFAULT NULL,
`custcreated` varchar(255) DEFAULT NULL,
`custmodified` varchar(255) DEFAULT NULL,
`cust_dataease_custid` int(11) DEFAULT NULL,
`custtype` varchar(5) DEFAULT NULL,
`custrep` int(11) DEFAULT NULL,
`custsource` varchar(5) DEFAULT NULL,
`custdiscount` decimal(65,30) DEFAULT NULL,
`custrepcomm` varchar(255) DEFAULT NULL,
`custsurcharge` varchar(255) DEFAULT NULL,
`custterms` varchar(12) DEFAULT NULL,
`custups` varchar(255) DEFAULT NULL,
`custnotes` varchar(255) DEFAULT NULL,
`custbilldif` varchar(5) DEFAULT NULL,
UNIQUE KEY `custid` (`custid`),
KEY `cust_dataease_custid_idx` (`cust_dataease_custid`),
KEY `custrep_idx` (`custrep`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `address` (
`addid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`addcustid` int(11) unsigned NOT NULL,
`addname` varchar(200) DEFAULT NULL,
`addtype` enum('b','s') NOT NULL DEFAULT 'b',
`address1` varchar(150) NOT NULL,
`address2` varchar(150) DEFAULT NULL,
`addcity` varchar(150) DEFAULT NULL,
`addstate` varchar(150) DEFAULT NULL,
`addstateother` varchar(150) DEFAULT NULL,
`addzip` varchar(150) DEFAULT NULL,
`addcountry` varchar(150) DEFAULT NULL,
`addnote` tinyblob,
PRIMARY KEY (`addid`),
KEY `add_cust_id_idx` (`addcustid`)
) ENGINE=InnoDB AUTO_INCREMENT=13037 DEFAULT CHARSET=utf8
John Green got me to thinking about the way information was being sent to and from the server, which led me to find the problem. Thanks John.
This is how I fixed it: Apparently, when my loop was iterating, it was "printing" each of the 8500 OPTION lines, which action (i didn't know), is a server-client interaction. So for each row, the server and browser had to have a conversation, which slowed everything down.
I fixed it by having the server compile the entire SELECT box on the server side, including the opening SELECT tags and interacting with the browser once through echoing my "add-to" variable: $select_box.
Now it takes like 1.2 seconds. I can live with that.
Thanks everyone for helping me chase this rabbit.
<?php // get the products
$select_box = "<select name=\"customer\" id=\"customer\" onChange=\"getcustinfo();\" data-placeholder=\"Choose a Customer\" class=\"chosen-select\" style=\"width:227px;\" tabindex=\"1\">
<option value=\"\"></option>";
$sql = "
SELECT *
FROM `cust`
LEFT Join `address`
ON `cust`.`custid` = `address`.`addcustid`
and `address`.`addtype` = 'b'
WHERE `cust`.`custactive` = 'y'"
;
$result = mysqli_query($con,$sql) or die('Query failed: Could not get list of CLIENTS: ' . mysqli_error($con)); // query
while ($row = mysqli_fetch_array($result)) {
foreach ($row as $key => $value){ ${$key} = $value; }
$space="";
$custname = substr($row['custname'],0,15);
$address1 = substr($row['address1'],0,15);
$addcity = substr($row['addcity'],0,15);
$select_box .= "<option value=\"$custid\">$custid: $space$custname, $address1, $addcity, $addstate</option>";
}
$select_box .="</select>";
echo $select_box;
?>