MySQL get Primary Key after Insert Statment - php

I need to use the following insert statement, and the primary key field is auto increment. I need to return the new primary key value after the insert. Preferably using one statement to do the insert and return primary key value.
$query = $database->connection->prepare("INSERT INTO accounts (created, priviledge, password, token, idle) VALUE ('$created', '1', :password, '$token_encrypt', '$idle')");
$query->bindParam(":password", $password_hash);
$query->execute();

As soon as you're using PDO you need to use
$database->connection->lastInsertId()
And it guarantees you to return the value from the current session. So answering to your question from comments - there is no chance you get the wrong value from a concurrent session.

Use mysql_insert_id(); to get the ID generated in the last query.
It retrieves the ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT).

assume your primary field name is id then try this code
SELECT max(id) FROM tableName
or try this
LAST_INSERT_ID();

DELIMITER $$
DROP TRIGGER IF EXISTS `TR_AI_mytable`;
CREATE TRIGGER `TR_AI_mytable` AFTER INSERT
ON `mytable` FOR EACH ROW
BEGIN
SET #mylastPK = new.PKField;
END;
$$

Related

Insert or update (if exists) without primary key

I have the following database MySQL table.
id (PK, AI)
email
country
lastlogin
I have a regular query in PHP that inserts this into the table.
however, logically, if this code runs several times, the same row will be inserted to the database every time.
I want my reference for checking and duplication to be the email field, and if the email is the same, update the country and the lastlogin.
I checked on other questions for a similar issue and the suggested way was to use ON DUPLICATE KEY like this
INSERT INTO <table> (field1, field2, field3, ...)
VALUES ('value1', 'value2','value3', ...)
ON DUPLICATE KEY UPDATE
field1='value1', field2='value2', field3='value3', ...
However, my primary key is not the email field rather the id but I don't want to run the check on it.
One option is make the email field unique, and then it should behave the same as primary key, at least with regard to MySQL's ON DUPLICATE KEY UPDATE:
ALTER TABLE yourTable ADD UNIQUE INDEX `idx_email` (`email`);
and then:
INSERT INTO yourTable (email, country, lastlogin)
VALUES ('tony9099#stackoverflow.com', 'value2', 'value3')
ON DUPLICATE KEY UPDATE
email='value1', country='value2', lastlogin='value3'
If the email tony9099#stackoverflow.com already exists in your table, then the update would kick in with alternative values.
From the MySQL documentation:
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row.
This approach doesn't only work with primary keys, it also works with any column having a unique index.
As Dan has mentioned, the ROW_COUNT() in-built function does not support this solution with a standard configuration.
MySQL::ROW_COUNT()
For UPDATE statements, the affected-rows value by default is the number of rows actually changed. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is the number of rows “found”; that is, matched by the WHERE clause.
If modifying the database schema is not an option, you could use the following method:
UPDATE `table` SET `country`='value1', `lastlogin`='value1' WHERE `email`='value3'
IF ROW_COUNT()=0
INSERT INTO `table` (`email`, `country`, `lastlogin`) VALUES ('value1', 'value2', 'value3')
you can use
$query=mysql_query("select * from table where email = 'your email'");
if(mysql_num_rows($query) > 0){
//update
}else{
//insert
}
You can load a row with the given email first and then decide if you have to insert or update depending on the existence of the loaded row. This needs multiple SQL statements, but it can be written in a DBMS vendor independent way. Use a surrounding transaction to handle concurrency. An index on the email-column is useful to keep the existence - check fast. Adding a unique - constraint on the email-column is an option to guarantee that there will never be multiple rows with same email.
You can do it manually like before inserting the value to table first check whether the value exists in table or not if yes then update your related field
$qry = mysql_query("select * from table where email='abc#abc.com'");
$count = mysql_num_rows($qry);
if($count > 0){
write your update query here
}else{
write your insert query here
}

How can I reset id to 0 in PHP MYSQL? [duplicate]

How can I reset the AUTO_INCREMENT of a field?
I want it to start counting from 1 again.
You can reset the counter with:
ALTER TABLE tablename AUTO_INCREMENT = 1
For InnoDB you cannot set the auto_increment value lower or equal to the highest current index. (quote from ViralPatel):
Note that you cannot reset the counter to a value less than or equal
to any that have already been used. For MyISAM, if the value is less
than or equal to the maximum value currently in the AUTO_INCREMENT
column, the value is reset to the current maximum plus one. For
InnoDB, if the value is less than the current maximum value in the
column, no error occurs and the current sequence value is not changed.
See How can I reset an MySQL AutoIncrement using a MAX value from another table? on how to dynamically get an acceptable value.
SET #num := 0;
UPDATE your_table SET id = #num := (#num+1);
ALTER TABLE your_table AUTO_INCREMENT =1;
Simply like this:
ALTER TABLE tablename AUTO_INCREMENT = value;
Reference: 13.1.9 ALTER TABLE Statement
There is a very easy way with phpMyAdmin under the "operations" tab. In the table options you can set autoincrement to the number you want.
The best solution that worked for me:
ALTER TABLE my_table MODIFY COLUMN ID INT(10) UNSIGNED;
COMMIT;
ALTER TABLE my_table MODIFY COLUMN ID INT(10) UNSIGNED AUTO_INCREMENT;
COMMIT;
It's fast, works with InnoDB, and I don't need to know the current maximum value!
This way. the auto increment counter will reset and it will start automatically from the maximum value exists.
The highest rated answers to this question all recommend "ALTER yourtable AUTO_INCREMENT= value". However, this only works when value in the alter is greater than the current max value of the autoincrement column. According to the MySQL 8 documentation:
You cannot reset the counter to a value less than or equal to the value that is currently in use. For both InnoDB and MyISAM, if the value is less than or equal to the maximum value currently in the AUTO_INCREMENT column, the value is reset to the current maximum AUTO_INCREMENT column value plus one.
In essence, you can only alter AUTO_INCREMENT to increase the value of the autoincrement column, not reset it to 1, as the OP asks in the second part of the question. For options that actually allow you set the AUTO_INCREMENT downward from its current max, take a look at Reorder / reset auto increment primary key.
As of MySQL 5.6 you can use the simple ALTER TABLE with InnoDB:
ALTER TABLE tablename AUTO_INCREMENT = 1;
The documentation are updated to reflect this:
13.1.7 ALTER TABLE Statement
My testing also shows that the table is not copied. The value is simply changed.
Beware! TRUNCATE TABLE your_table will delete everything in your your_table.
You can also use the syntax TRUNCATE table like this:
TRUNCATE TABLE table_name
ALTER TABLE news_feed DROP id
ALTER TABLE news_feed ADD id BIGINT( 200 ) NOT NULL AUTO_INCREMENT FIRST ,ADD PRIMARY KEY (id)
I used this in some of my scripts. The id field is dropped and then added back with previous settings. All the existent fields within the database table are filled in with the new auto increment values. This should also work with InnoDB.
Note that all the fields within the table will be recounted and will have other ids!!!.
It is for an empty table:
ALTER TABLE `table_name` AUTO_INCREMENT = 1;
If you have data, but you want to tidy up it, I recommend to use this:
ALTER TABLE `table_name` DROP `auto_colmn`;
ALTER TABLE `table_name` ADD `auto_colmn` INT( {many you want} ) NOT NULL AUTO_INCREMENT FIRST ,ADD PRIMARY KEY (`auto_colmn`);
To update to the latest plus one id:
ALTER TABLE table_name AUTO_INCREMENT =
(SELECT (id+1) id FROM table_name order by id desc limit 1);
Edit:
SET #latestId = SELECT MAX(id) FROM table_name;
SET #nextId = #latestId + 1;
ALTER TABLE table_name AUTO_INCREMENT = #nextId;
Not tested please test before you run*
Warning: If your column has constraints or is connected as a foreign key to other tables this will have bad effects.
First, drop the column:
ALTER TABLE tbl_name DROP COLUMN column_id
Next, recreate the column and set it as FIRST (if you want it as the first column I assume):
ALTER TABLE tbl_access ADD COLUMN `access_id` int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST
As of MySQL 5.6 the approach below works faster due to online DDL (note algorithm=inplace):
alter table tablename auto_increment=1, algorithm=inplace;
SET #num := 0;
UPDATE your_table SET id = #num := (#num+1);
ALTER TABLE your_table AUTO_INCREMENT =1;
ALTER TABLE tablename AUTO_INCREMENT = 1
Try to run this query:
ALTER TABLE tablename AUTO_INCREMENT = value;
Or try this query for the reset auto increment
ALTER TABLE `tablename` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL;
And set auto increment and then run this query:
ALTER TABLE `tablename` CHANGE `id` `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT;
The auto-increment counter for a table can be (re)set in two ways:
By executing a query, like others already explained:
ALTER TABLE <table_name> AUTO_INCREMENT=<table_id>;
Using Workbench or another visual database design tool. I am going to show in Workbench how it is done - but it shouldn't be much different in other tools as well. By right clicking over the desired table and choosing Alter table from the context menu. On the bottom you can see all the available options for altering a table. Choose Options and you will get this form:
Then just set the desired value in the field Auto increment as shown in the image. This will basically execute the query shown in the first option.
If you're using PHPStorm's database tool you have to enter this in the database console:
ALTER TABLE <table_name> AUTO_INCREMENT = 0;
I tried to alter the table and set auto_increment to 1 but it did not work. I resolved to delete the column name I was incrementing, then create a new column with your preferred name and set that new column to increment from the onset.
I googled and found this question, but the answer I am really looking for fulfils two criteria:
using purely MySQL queries
reset an existing table auto-increment to max(id) + 1
Since I couldn't find exactly what I want here, I have cobbled the answer from various answers and sharing it here.
Few things to note:
the table in question is InnoDB
the table uses the field id with type as int as primary key
the only way to do this purely in MySQL is to use stored procedure
my images below are using SequelPro as the GUI. You should be able to adapt it based on your preferred MySQL editor
I have tested this on MySQL Ver 14.14 Distrib 5.5.61, for debian-linux-gnu
Step 1: Create Stored Procedure
create a stored procedure like this:
DELIMITER //
CREATE PROCEDURE reset_autoincrement(IN tablename varchar(200))
BEGIN
SET #get_next_inc = CONCAT('SELECT #next_inc := max(id) + 1 FROM ',tablename,';');
PREPARE stmt FROM #get_next_inc;
EXECUTE stmt;
SELECT #next_inc AS result;
DEALLOCATE PREPARE stmt;
set #alter_statement = concat('ALTER TABLE ', tablename, ' AUTO_INCREMENT = ', #next_inc, ';');
PREPARE stmt FROM #alter_statement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
Then run it.
Before run, it looks like this when you look under Stored Procedures in your database.
When I run, I simply select the stored procedure and press Run Selection
Note: the delimiters part are crucial. Hence if you copy and paste from the top selected answers in this question, they tend not to work for this reason.
After I run, I should see the stored procedure
If you need to change the stored procedure, you need to delete the stored procedure, then select to run again.
Step 2: Call the stored procedure
This time you can simply use normal MySQL queries.
call reset_autoincrement('products');
Originally from my own SQL queries notes in https://simkimsia.com/reset-mysql-autoincrement-to-max-id-plus-1/ and adapted for Stack Overflow.
delete from url_rewrite where 1=1;
ALTER TABLE url_rewrite AUTO_INCREMENT = 1;
and then reindex
ALTER TABLE `table_name` DROP `id`;
ALTER TABLE `table_name` ADD `id` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`id`) ;
Shortly,First we deleted id column then added it with primary key id again...
The best way is remove the field with AI and add it again with AI. It works for all tables.
You need to follow the advice from Miles M's comment and here is some PHP code that fixes the range in MySQL. Also you need to open up the my.ini file (MySQL) and change max_execution_time=60 to max_execution_time=6000; for large databases.
Don’t use "ALTER TABLE tablename AUTO_INCREMENT = 1". It will delete everything in your database.
$con = mysqli_connect($dbhost, $dbuser, $dbpass, $database);
$res = mysqli_query($con, "select * FROM data WHERE id LIKE id ORDER BY id ASC");
$count = 0;
while ($row = mysqli_fetch_array($res)){
$count++;
mysqli_query($con, "UPDATE data SET id='".$count."' WHERE id='".$row['id']."'");
}
echo 'Done reseting id';
mysqli_close($con);
I suggest you to go to Query Browser and do the following:
Go to schemata and find the table you want to alter.
Right click and select copy create statement.
Open a result tab and paste the create statement their.
Go to the last line of the create statement and look for the Auto_Increment=N,
(Where N is a current number for auto_increment field.)
Replace N with 1.
Press Ctrl + Enter.
Auto_increment should reset to one once you enter a new row in the table.
I don't know what will happen if you try to add a row where an auto_increment field value already exist.

LAST_INSERT_ID not working on UPDATE

if I use this SQL:
UPDATE formulare SET EV_id=59, EV_status=5 WHERE EV_id=57 AND ID_uziv=12;SELECT LAST_INSERT_ID();
I will get 0 as last insert id.
I'm using php mysqli_insert_id and here is said that:
The mysqli_insert_id() function returns the ID generated by a query
on a table with a column having the AUTO_INCREMENT attribute.
If the last query wasn't an INSERT or UPDATE statement
or if the modified table does not have a column with the AUTO_INCREMENT attribute,
this function will return zero.
my table formualre has auto increment column, so I don't know wher the problem is
LAST_INSERT_ID() won't work if no new auto increment value was created.
The solution is something like this:
UPDATE formulare
SET EV_id=LAST_INSERT_ID(59),
EV_status=5
WHERE EV_id=57
AND ID_uziv=12;
SELECT LAST_INSERT_ID();
Note: I guess, that EV_id is the auto_increment primary key.
Otherwise you should do a query like:
UPDATE formulare
SET key_col = LAST_INSERT_ID(key_col),
EV_id=59,
EV_status=5
WHERE EV_id=57
AND ID_uziv=12;
SELECT LAST_INSERT_ID();
From the documentation :
The ID generated for an AUTO_INCREMENT column by the previous query on
success, 0 if the previous query does not generate an AUTO_INCREMENT
value, or FALSE if no MySQL connection was established.
As your update didn't create a new record, it didn't generate any AUTO_INCREMENT value.
UPDATE query updates the existing record, it doesn't return any new ID.
mysqli_insert_id retrieves the ID generated for an AUTO_INCREMENT column by the
previous query (usually INSERT).
There was no INSERT query, that's the reason, you won't get any Id after executing UPDATE query.
For more info, refer mysql_insert_id

php mySQL pdo auto_increment primary key for row

How do you set allow mySQL to auto increment a row in mySQL when using php? I have set the link_id column as auto_increment using phpMyAdmin but I do not know how to get the row to auto increment when using PDO.
$preparedStatement = $con->prepare('INSERT INTO link (link_id, category, link_desc, link_url) VALUES (:link_id, :category, :link_desc, :link_url)');
$preparedStatement-> execute(array(':link_id' => **AUTO INCREMENT Field in mySQL**, ':category' => $category,':link_desc' => $link_desc,':link_url' => $link_url));
Thanks for the help in advance!
You don't have to do anything special with PHP, but there are several ways in MySQL. One is to use a falsey value or null:
INSERT INTO link (<columns>) VALUES (null, category...
Just exclude the parameter in PHP.
You can also specify columns to insert, and if you leave off the auto_increment key, it gets auto incremented:
INSERT INTO link (category, link_desc...)
You can fill the AUTO_INCREMENT column at INSERT statement with any value ...
MySQL automatically will override AUTO_INCREMENT column value that are defined into your statement and handle with new value correctly.
In console mode it generates a warning if the value wasn't set correctly, but in PHP i think it will be ignored.

Conditional mySQL statement. If true UPDATE, if false INSERT [duplicate]

This question already has answers here:
MySQL 'UPDATE ON DUPLICATE KEY' without a unique column?
(3 answers)
Closed 10 months ago.
I'm trying to create more robust MySQL Queries and learn in the process. Currently I'm having a hard time trying to grasp the ON DUPLICATE KEY syntax and possible uses.
I have an INSERT Query that I want to INSERT only if there is no record with the same ID and name, otherwise UPDATE. ID and name are not UNIQUE but ID is indexed.ID isn't UNIQUE because it references another record from another table and I want to have multiple records in this table that reference that one specific record from the other table.
How can I use ON DUPLICATE KEY to INSERT only if there is no record with that ID and name already set else UPDATE that record?
I can easily achieve this with a couple of QUERIES and then have PHP do the IF ELSE part, but I want to know how to LIMIT the amount of QUERIES I send to MySQL.
UPDATE: Note you need to use IF EXISTS instead of IS NULL as indicated in the original answer.
Code to create stored procedure to encapsulate all logic and check if Flavours exist:
DELIMITER //
DROP PROCEDURE `GetFlavour`//
CREATE PROCEDURE `GetFlavour`(`FlavourID` INT, `FlavourName` VARCHAR(20))
BEGIN
IF EXISTS (SELECT * FROM Flavours WHERE ID = FlavourID) THEN
UPDATE Flavours SET ID = FlavourID;
ELSE
INSERT INTO Flavours (ID, Name) VALUES (FlavourID, FlavourName);
END IF;
END //
DELIMITER ;
ORIGINAL:
You could use this code. It will check for the existence of a particular record, and if the recordset is NULL, then it will go through and insert the new record for you.
IF (SELECT * FROM `TableName` WHERE `ID` = 2342 AND `Name` = 'abc') IS NULL THEN
INSERT INTO `TableName` (`ID`, `Name`) VALUES ('2342', 'abc');
ELSE UPDATE `TableName` SET `Name` = 'xyz' WHERE `ID` = '2342';
END IF;
I'm a little rusty on my MySQL syntax, but that code should at least get you most of the way there, rather than using ON DUPLICATE KEY.
id and name are not unique but id is
indexed. id isn't unique
How can I use ON DUPLICATE KEY to
INSERT only if there is no record with
that id and name already set else
UPDATE that record?
You can't. ON DUPLICATE KEY UPDATE needs a unique or primary key to determine which row to update. You are better off having PHP do the IF ELSE part.
edit:
If the combination of name and id IS supposed to be unique, you can create a multi-column UNIQUE index. From there you can use ON DUPLICATE KEY UPDATE.
Why not just use a stored procedure, then you can embed all the logic there are plus you have a reusable piece of code (e.g. the stored proc) that you can use in other applications. Finally, this only requires one round trip to the server to call the stored proc.

Categories