mysql updating last inserted id - mysql

I want to update a table by getting the last inserted id but it is giving no results.
here is the query :
$quer = mysql_query("UPDATE date
SET d_startdate = '$start', d_enddate = '$end'
WHERE d_id = LAST_INSERT_ID() AND d_sid = $id");
d_id is the primary key and d_sid is a foreign key of another table

I have used INSERT as well as UPDATE operation on my same table and its working fine. You can change this query as per your need.
<?php
$con = mysql_connect("localhost","root","") or die("Could not connect");
mysql_selectdb("test", $con);
$query = 'INSERT INTO item (`name`) VALUES ("DELTaaaA")';
$res = mysql_query($query, $con) or die(mysql_error());
echo "<pre>";
print_r($res);
$query = 'UPDATE item set name="DELTaaaA1" WHERE id = LAST_INSERT_ID()';
$res = mysql_query($query, $con) or die(mysql_error());
print_r($res);
?>
It should return 1 1

use code like this before that
SELECT LAST_INSERT_ID() and assign this to a variable, then use that variable in your code

I don't know the normal syntax, but PDO syntax is quiet simple, you can get last inserted id by the function PDO::lastInsertId() use it as $myPDOobject->lastInsertId() . More information here : http://php.net/manual/en/pdo.lastinsertid.php

LAST_INSERT_ID gives you the id of the most recent insert.
Suppose that you added a row which has d_id=10 (d_id set by auto increment) and d_sid=20 and then another one with d_id=11 (again, auto increment) and d_sid=30.
You then want to look for the most recent insert with d_sid=20, but doing this with LAST_INSERT_ID is not possible, since LAST_INSERT_ID has value 11, and no row matches with that d_id and d_sid=20. You have to keep track by yourself of the most recent d_id for each category, most likely when you insert the new rows.
Do the INSERT
SELECT the LAST_INSERT_ID (name it L_ID)
Store the tuple <d_sid, L_ID> somewhere, so you know that for d_sid your most recent INSERT has value L_ID
UPDATE your table where the d_sid is the one you want and d_id is taken from the tuple
As a side note, mysql_* is deprecated, so you should switch to something else like mysqli or PDO.

Related

How to Duplicate Records in the same MySQL Table Using the Inserted IDs

I have 2 tables. The first table is tbl_items and the second table is tbl_items_extras.
I insert my Items into tbl_items and if in case this item has a single/multiple extras, they will be inserted in the table tbl_items_extras where tbl_items.id=tbl_items_extras.tbl_items_id.
Below is the screenshot of my two tables.
I was able to duplicate the records for tbl_items perfectly using the below query;
INSERT INTO `tbl_items` (`items_ref_id`, `rev`, `die_number`, `product_type_id`, `parts_id`, `complexity_id`)
SELECT
q.`items_ref_id`,
q.`rev`+1,
q.`die_number`,
q.`product_type_id`,
q.`parts_id`,
q.`complexity_id`
FROM `tbl_items` q WHERE `items_ref_id`='$refNum' AND `rev`='$maxRev'
But when I duplicate the tbl_items_extras records using the below query;
INSERT INTO `tbl_items_extras` (`tbl_items_id`, `extras_conditions_id`, `percentage`, `quantity`, `total_percentage`)
SELECT
q.`tbl_items_id`,
q.`extras_conditions_id`,
q.`percentage`,
q.`quantity`,
q.`total_percentage`
FROM `tbl_items_extras` q WHERE `tbl_items_id` IN (SELECT `id` FROM `tbl_items` WHERE `items_ref_id`='$refNum' AND `rev`='$rev')
In this query, I didn't get what I need exactly. See the below screenshot.
What I need is to duplicate selected records in tbl_items_extras where the tbl_items_id has to be the SQL_INSERTED_ID of the duplicated records in tbl_items.
The result should be as per the below screenshot.
As you can see, the tbl_items.id was used accordingly in the tbl_items_extras.tbl_items_id.
I know I can use the LAST_INSERT_ID but this works only for a single record.
I found an answer to my question.
I put my DUPLICATE QUERY inside a WHILE LOOP where I fetched the id of each row.
While tbl_items duplicates the record it will duplicate the tbl_items_extras using the fetched id and insert the $inserted_tbl_items_id in the tbl_items_extras.tbl_items_id.
$stmt = $connect->prepare("SELECT * FROM `tbl_items` WHERE `items_ref_id`= ? AND `rev`= ?");
$stmt->bind_param("ii", $refNum, $maxRev);
$stmt->execute();
$result = $stmt->get_result();
// duplicate tbl_items
if($result->num_rows === 0) exit('No rows');
while($row = $result->fetch_assoc()) {
$id = $row['id'];
// I put my tbl_items DUPLICATE QUERY (same as the above)
$inserted_tbl_items_id = $connect->insert_id; // get inserted id
// and my tbl_items_extras DUPLICATE QUERY
$sql = "INSERT INTO `tbl_items_extras` (`tbl_items_id`, `extras_conditions_id`, `percentage`, `quantity`, `total_percentage`)
SELECT
'$inserted_tbl_items_id',
q.`extras_conditions_id`,
q.`percentage`,
q.`quantity`,
q.`total_percentage`
FROM `tbl_items_extras` q WHERE `tbl_items_id` IN (SELECT `id` FROM `tbl_items` WHERE `id`='$id')";
$connect->query($sql);
}

MySql auto_increment plus a certain number

I want my the id field in my table to be a bit more " random" then consecutive numbers.
Is there a way to insert something into the id field, like a +9, which will tell the db to take the current auto_increment value and add 9 to it?
Though this is generally used to solve replication issues, you can set an increment value for auto_increment:
auto_increment_increment
Since that is both a session and a global setting, you could simply set the session variable just prior to the insert.
Besides that, you can manually do it by getting the current value with MAX() then add any number you want and insert that value. MySQL will let you know if you try to insert a duplicate value.
You have a design flaw. Leave the auto increment alone and shuffle your query result (when you fetch your data)
As far as i know, it's not possible to 'shuffle' your current IDs. If you wanted though, you could pursue non-linear IDs in the future.
The following is written in PDO, there are mysqli equivalents.
This is just an arbitrary INSERT statement
$name = "Jack";
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$sql = "INSERT INTO tableName (name) VALUES(:name)";
$q = $conn->prepare($sql);
$q->execute(':name' => $name);
Next, we use lastInsertId() to return the ID of the last inserted row, then we concatenate the result to rand()
$lastID = $conn->lastInsertId();
$randomizer = $lastID.rand();
Finally, we use our 'shuffled' ID and UPDATE the previously inserted record.
$sql = "UPDATE tableName SET ID = :randomizer WHERE ID=:lastID ";
$q = $conn->prepare($sql);
$q->execute(array(':lastID' => $lastID , ':randomizer' => $randomizer));
An idea.. (Not tested)
CREATE TRIGGER 'updateMyAutoIncrement'
BEFORE INSERT
ON 'DatabaseName'.'TableName'
FOR EACH ROW
BEGIN
DECLARE aTmpValueHolder INT DEFAULT 0;
SELECT AUTO_INCREMENT INTO aTmpValueHolder
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'DatabaseName'
AND TABLE_NAME = 'TableName';
SET NEW.idColumnName =aTmpValueHolder + 9;
END;
Edit : If the above trigger doesn't work try to update AUTO_INCREMENT value directly into the system's schema. But as noted by Eric, your design seems to be flawed. I don't see the point of having an auto-increment here.
Edit 2 : For a more 'random' and less linear number.
SET NEW.idColumnName =aTmpValueHolder + RAND(10);
Edit 3 : As pointed out by Jack Williams, Rand() produces a float value between 0 and 1.
So instead, to produce an integer, we need to use a floor function to transform the 'random' float into an integer.
SET NEW.idColumnName =aTmpValueHolder + FLOOR(a + RAND() * (b - a));
where a and b are the range of the random number.

Use insert id in a query?

I'm inserting into my pics table:
id | name
1 | dog.gif
I also want to get the id of the above insert (1) and inset that in to another table (gallery table).
Is it possible to do this in one query or would I need two?
INSERT INTO pic SET .... ;
INSERT INTO gallery SET pic_id = LAST_INSERT_ID(), ....
Since it is serial you can use select max(id) from tableName
But that's vulnerable to errors on simultaneous updates so use the method described below
From php.net clickhere
<?php
$link = mysqli_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysqli::$connect_error() );
}
mysqli::select_db('mydb');
mysqli::query("INSERT INTO mytable (product) values ('kossu')");
printf("Last inserted record has id %d\n", mysqli::$insert_id());
?>
But you need to connect for every query.

mysql - insert many to many relationship

I am trying to insert records in 2 different mysql tables. Here's the situation:
Table 1: is_main that contains records of resorts with a primary key called id.
Table 2: is_features that contains a list of features that a resort can have (i.e. beach, ski, spa etc...). Each feature has got a primary key called id.
Table 3: is_i2f to connect each resort id with the feature id. This table has got 2 fields: id_i and id_f. Both fields are primary key.
I have created a form to insert a new resort, but I'm stuck here. I need a proper mysql query to insert a new resort in the is_main table and insert in is_i2f one record for each feature it has, with the id of the resort id id_i and the id of the feature id id_f.
$features = ['beach','relax','city_break','theme_park','ski','spa','views','fine_dining','golf'];
mysql_query("INSERT INTO is_main (inv_name, armchair, holiday, sipp, resort, price, rooms, inv_length, more_info)
VALUES ('$name', '$armchair', '$holiday', '$sipp', '$resort', '$price', '$rooms', '$length', '$more_info')");
$id = mysql_insert_id();
foreach($features as $feature) {
if(isset($_POST[$feature])) {
$$feature = 1;
mysql_query("INSERT INTO is_i2f (id_i, id_f) VALUES (" . $id . ", ?????????????? /missing part here????/ ); }
else {
$$feature = 0; }
}
Thanks.
Please, I'm going CrAzY!!!!!!!!!!!!!!
This may not be relevant to you, but...
Would it not make more sense to leave the link table unpopulated? You can use JOINs to then select what you need to populate the various views etc in your application
i.e. query to get 1 resort with all features:
SELECT
Id,
f.Id,
f.Name
FROM IS_MAIN m
CROSS JOIN IS_FEATURES f
WHERE m.Id = $RequiredResortId
Please find the answer on Mysql insert into 2 tables.
If you want to do multiple insert at a time you can write a SP to fulfill your needs
If I understand you correctly you could concatenate variable amount of to be inserted/selected values into one query. (This is the second query which needs an id from the first.)
//initializing variables
$id = mysql_insert_id();
$qTail = '';
$i = -1;
//standard beginning
$qHead = "INSERT INTO `is_i2f` (`id`,`feature`) VALUES ";
//loop through variable amount of variables
foreach($features] as $key => $feature) {
$i++;
//id stays the same, $feature varies
$qValues[$i] = "('{$id}', '{$feature}')";
//multiple values into one string
$qTail .= $qValues[$i] . ',';
} //end of foreach
//concatenate working query, need to remove last comma from $qTail
$q = $qHead . rtrim($qTail, ',');
Now you should have a usable insert query $q. Just echo it and see how it looks and test if it works.
Hope this was the case. If not, sorry...

generating MD5 idHash directly in MySQL statement

In my table I have an userID that is auto-incremented. In the same row I have an idHash. Is it possible to generate the idHash (simply an MD5 sum) from it directly with the same INSERT statement so that I don't have to SELECT the id, and then UPDATE the idHash again?
Problem is: I do not know the userID before it is being generated (auto-incremented) by MySQL.
Thanks
Frank
PS: I'm using PHP.
PPS: This question is all about a SINGLE INSERT. I know that I can use PHP or other languages to manually select the data and then update it.
I don't believe you can do it within a single INSERT statement.
What you probably could do is use an INSERT trigger, that both determines the new ID, hashes it, and then updates the record.
One solution I can recommend is using the last insert ID instead of re-querying the table. Here is a simplified example:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "INSERT INTO users VALUES (....)";
$mysqli->query($query);
$newUserID = $mysqli->insert_id;
$query = "UPDATE users SET idHash = MD5(userID) WHERE userID = $newUserID";
$mysqli->query($query);
/* close connection */
$mysqli->close();
?>
AFAIK there's no "secure" way for doing this in the same query if you're using auto_increment.
However, if rows are never deleted in your table, you can use this little trick :
insert into mytable (col1, col2, col3, idhash)
values ('', '', '', md5(select max(id) from mytable))
I don't understand why you need to hash the id though, why not use the id directly ?
This seems to work for me:
CREATE TABLE tbl (id INT PRIMARY KEY AUTO_INCREMENT, idHash TEXT);
INSERT INTO tbl (idHash) VALUES (MD5(LAST_INSERT_ID() + 1));
SELECT *, MD5(id) FROM tbl;
Note this will only work on single-row inserts as LAST_INSERT_ID returns the insert ID of the first row inserted.
Performing MD5(column_name) on an auto_increment value does not work as the value has not been generated yet, so it is essentially calling MD5(0).
PHP snippet
<?
$tablename = "tablename";
$next_increment = 0;
$qShowStatus = "SHOW TABLE STATUS LIKE '$tablename'";
$qShowStatusResult = mysql_query($qShowStatus) or die ( "Query failed: " . mysql_error() . "<br/>" . $qShowStatus );
$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];
echo "next increment number: [$next_increment]";
?>
This will get you the next auto-increment and then you can use this in your insert.
Note: This is not perfect (Your method is imperfect as you will effectively have 2 primary keys)
From: http://blog.jamiedoris.com/geek/560/