I am copying a row in one of the tables in my database and trying to get the last inserted ID. Copying the row works fine, and the AI field updates properly, but it is not returning the last insert ID (although it does return true - or if I echo something else out in its place that works fine as well).
Some of the other queries also use last insert ID and those work well.
I suspect it is something to do with the temporary table, but cannot find anything on SO about a similar problem with last insert ID and temporary tables. Does anyone know what is causing the problem or if there is a workaround?
public function duplicateItinRow($itineraryID){
$this->db->query("CREATE TEMPORARY TABLE temporary_itin_table AS SELECT * FROM itinerary_ref WHERE Itinerary_ID = $itineraryID;
UPDATE temporary_itin_table SET Itinerary_ID=NULL;
INSERT INTO itinerary_ref SELECT * FROM temporary_itin_table;
DROP TEMPORARY TABLE temporary_itin_table");
//Execute
if($this->db->execute()){
return $this->db->lastInsertId();
} else {
return false;
}
}
UPDATE:
Not the ideal solution I'm sure, but have got it working using the copy method detailed here: How to copy a row and insert in same table with a autoincrement field in MySQL?
I think lastInsertedId will be updated by your last "DROP TEMPORARY TABLE" statement.
Try to split the query into two separate queries instead:
<?php
public function duplicateItinRow($itineraryID) {
$this->db->query("CREATE TEMPORARY TABLE temporary_itin_table AS SELECT * FROM itinerary_ref WHERE Itinerary_ID = $itineraryID;
UPDATE temporary_itin_table SET Itinerary_ID=NULL;
INSERT INTO itinerary_ref SELECT * FROM temporary_itin_table;");
if(!$this->db->execute()) {
return false;
}
$lastId = $this->db->lastInsertId();
$this->db->query("DROP TEMPORARY TABLE temporary_itin_table");
if(!$this->db->execute()) {
return false;
}
return $lastId;
}
Also note that you have a SQL injection vulnerability when you add $itineraryID directly to the SQL query without using prepared statements. If the $itineraryID is populated from user input people can hack your website.
Related
I am trying to enter a whole table in itself changing the city variable but when I create a temp table to store data the insert statement to insert data back in original statement not working. Here is the code
<?php
if(isset($_POST['btnsub'])){
$city=$_POST['city'];
$query= $conn->query("create table from_php like menuinstant;
insert into from_php select * from menuinstant where city='Kota';
update from_php set id = replace(id,'Kota','.$city.');
update from_php set city = replace(city,'Kota','.$city.');
insert into menuinstant select * from from_php;
drop table from_php
");
echo "table created";
}
?>
The insert into menuinstant is not executing even the drop query after that is also working. Help me out.
almost all database/sql wrappers will only allow exactly ONE query per call. so your $conn->query([5queries]) should be five $conn->query([1stquery]); $conn->query([2ndquery]); ...
update1:
You should/could also check for errors:
$result = $conn->query('[Your query here]');
if($result === false) {
die(print_r($conn->errorInfo(),true));
}
update2: please read up on mysql injections. for example http://php.net/manual/en/security.database.sql-injection.php
i want to get datas from a mySQL table and want to insert every row (that my query get) into another table.
With following code i get my Datas:
$cart = new Dbconn();
$query = new Dbconn();
if ($cart->pdo()) {
$cart->stmt("SELECT id, product FROM cart WHERE uid =:uid");
$cart->bindParam(':uid', Session::get('uid'));
$cart->exe();
}
After i get the data i want to insert it, with a while loop
while ($rowPay = $cart->fetch()) {
if ($query->pdo()) {
$query->stmt('INSERT INTO orders (products_id, order_id) VALUES(:uid, :products)');
$query->bindParam(':user_id', Session::get('uid'));
$query->bindParam(':products', $rowPay['product']);
$query->exe();
}
}
He get all Datas but insert only the first entry. Where is my mistake?
Greetings
If it insert only the first entry, then there is a problem with the parameters you try to insert.
You probably try to insert several rows with the same primary key.
I need to know where is the primary key in each table in order to help you more.
$payCart->fetch() fetches single row and $payCart->fetchAll() fetches all rows.
Try as this
while ($rowPay = $payCart->fetchAll(PDO::FETCH_ASSOC)) {
if ($query->pdo()) {
$query->stmt('INSERT INTO orders'
.'(products_id, order_id)'
.'VALUES(:uid, :products)');
$query->bindParam(':user_id', Session::get('uid'));
$query->bindParam(':products', $rowPay['product']);
$query->exe();}}
I have a script that I have setup a CRON for that is getting values from a 3rd party server via JSON (cURL)
Right now every time the cron runs it will INSERT a completely new record. Causing duplicates, and resulting me in manually removing the dups.
How would I go about preventing duplicates, and only update the information that is either missing, or different from the NEW $VAR values?
What I want to do can be expressed like this: IF old value is NOT new value use new value else use old value;
if ($stmt->num_rows !== 1) {
if ($insert_stmt = $mysqli->prepare("
INSERT INTO members (
start_date
)
VALUES (?)"))
{
$insert_stmt->bind_param('s',
$StartDate,
);
if (! $insert_stmt->execute()) { echo ''; }
}
}
}
You should try using INSERT ... ON DUPLICATE KEY UPDATE. Documentation
This does mean that you will have to define some unique (could be primary) key to the table that is always constant so MySQL knows what to update.
A quick example of how you would do it:
INSERT INTO table (f1,f2,f3) VALUES ('something_unique',2,5)
ON DUPLICATE KEY UPDATE f2=2,f3=5
The following statement will be silently ignored if one of the fields with the flags UNIQUE or PRIMARY KEY already exist in the database. If you're searching for INSERT IF NOT EXISTS this is probably what you're looking for:
INSERT IGNORE INTO `members` SET name='Steve',start_date='2015-11-20';
You can also overwrite a record that already exists using REPLACE. If it doesn't yet exist, it will be created:
REPLACE INTO `members` SET name='Steve',start_date='2015-11-20';
Another thing to consider would be INSERT ... ON DUPLICATE KEY UPDATE syntax:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
I ended up writing another if statement to check if a unique value existed from incoming and the existing db value existed and leaving it blank to prevent it from importing duplicates. I also wrote a separate file to update where values differentiate between what I am receiving as (new) and what is in the database (old) which actually worked out great for my application.
Here is my answer for anyone else that runs into this issue :)
$prep_stmt = "SELECT * FROM table WHERE column_keys=?";
$stmt = $mysqli->prepare($prep_stmt);
if ($stmt) {
$stmt->bind_param('s',$varvalues);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows == 1) {
if ($insert_stmt = $mysqli->prepare("")) {
$insert_stmt->bind_param('');
if (! $insert_stmt->execute()) {
echo 'shits broke'; }
}
}
else { if ($insert_stmt = $mysqli->prepare("
INSERT INTO table (column_keys)
VALUES (?)")) // you will need a ? per column seperate by a , (?,?,?...?)
{ $insert_stmt->bind_param('s',
$varvalues
); // you will also need to bind a 's' (string) 'i' for num, etc per $var value.
if (! $insert_stmt->execute()) { echo 'shits broke';} //lol
}
}
}
Also a simple error reporting trick I stumbled upon that helped me clean up a few things I overlooked. Just place it at the top of the file, or above you want to debug ;)
error_reporting(E_ALL);
Maybe it's just me, but I couldn't find an answer to the exact problem I'm having anywhere else. I have a function that inserts a record in my db like this:
function createOpdrachtInstance($opdracht, $bedrijf, $deelnemer) {
$db = dbConnection();
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$query = "INSERT INTO opdrachten_deelnemers (`opdracht_id`,`bedrijf_id`,`deelnemer_id`,`flag`) VALUES (:opdracht_id,:bedrijf_id,:deelnemer_id,:flag)";
$q = $db->prepare($query);
$q->execute(array(':opdracht_id'=>$opdracht,
':bedrijf_id'=>$bedrijf,
':deelnemer_id'=>$deelnemer,
':flag'=>0));
}
Works fine. But if a record that is exactly the same allready exists (all rows except id) it shouldn't be inserted. I have found how this works for 1 row but not how it works for multiple rows. How can I implement this in my function?
$query = "INSERT IGNORE INTO opdrachten_deelnemers (`opdracht_id`,`bedrijf_id`,`deelnemer_id`,`flag`) VALUES (:opdracht_id,:bedrijf_id,:deelnemer_id,:flag)";
Hope this helps
I presume you meant columns rather than rows " (all rows except id) "? If this were me I would use a storedprocedure which has the logic test within to find if a record with these values aready exists. If the record exists, do nothing else add record.
I have a form button that I need to do two different things, based on user input and whether that input already exists in my database. If the input DOES NOT exist, then the button will create a new record. If it DOES exist, then the existing record will be updated.
Here's my PDO query as it stands now:
/* First, we need to discover whether the Proposal No. entered already exists in the
database. If it doesn't, then a new record will be created. If
it does, then an existing record will be updated. */
$pNoExists = $con->prepare("SELECT ProposalNo FROM ptfp1");
$pNoExists->execute();
$row = $pNoExists->fetch(PDO::FETCH_ASSOC);
When I run $row = $pNoExists->fetch(PDO::FETCH_ASSOC); through a while loop, all of the values for the field are present. Now I just need some guidance on how to use that in my button setup. This is what I want to do:
if($_POST['ButtonPush'] && input doesn't exist) {
Create new record;
}
else {
Update existing record;
}
Simple, right? But it's eluding me.
Given what you have, I would do:
if($_POST['ButtonPush'] && array_search($all_values, $input_value)) {
Create new
}
else {
Update
}
However, like the comment above, you may want to simply add a where clause to your "SELECT" statement so you are not grabbing the entire database table contents every time. And, one could even convert the SELECT in to a SELECT COUNT to bring down the amount of data being requested.
You could use SELECT count(*) FROM ptfp1 WHERE ProposalNo = :input
Than check if the value you get is bigger than one. If it is, update it:
UPDATE ptfp1 set ... where ProposalNo = :input
else
INSERT INTO ptfp1(...) VALUES (...)
Assuming ProposalNo has a unique index in the table, you can do it all in one query:
INSERT INTO ptfp1 (ProposalNo, colA, colB, colC, ...)
VALUES (:ProposalNo, :colA, :colB, :colC, ...)
ON DUPLICATE KEY
UPDATE colA = VALUES(colA), colB = VALUES(colB), colC = VALUES(colC), ...
Documentation
Figured out an answer. Just use the user's input (stored in a session variable) in my SELECT statement:
$pNoExists = $con->prepare("SELECT ProposalNo FROM ptfp1 WHERE ProposalNo =
'".$_SESSION['ProposalNo']."'");
$pNoExists->execute();
$row = $pNoExists->fetch(PDO::FETCH_ASSOC);
And the button:
if($_POST['ButtonPush'] && !$row['ProposalNo']) {
Write new record;
}
else {
Update existing record;
}
Hiding in plain sight!