How to store the auto increment value into a php variable? - php

I have written my sql below and it works. As I've set my particulars_id to autoincrement, i have to use Last_Insert_ID() in order for the database to use the next id using auto increment. However, i would like to store that value into a php variable. Is that possible?
$addquery = "INSERT INTO Particulars (Particulars_ID, Name, Identification_Number, Number, Nationality, Status, Remarks)
VALUES(LAST_INSERT_ID(),'$_POST[newname]', '$_POST[newic]','$_POST[newnumber]','$_POST[newnationality]','$_POST[newstatus]','$_POST[newremarks]')";

When you insert a row into a table that has an AUTO_INCREMENT field that field will be incremented automatically as the name implies. You don't need to tell MySQL to increment it, you don't have to provide a value for the auto-increment field at all.
So to begin with, remove the call to LAST_INSERT_ID() from your query:
$addquery = "INSERT INTO Particulars (Name, Identification_Number, Number, Nationality, Status, Remarks)
'$_POST[newname]', '$_POST[newic]','$_POST[newnumber]','$_POST[newnationality]','$_POST[newstatus]','$_POST[newremarks]')";
Notice how I completely removed the Particulars_ID from the query.
Second, this is not directly related to your question but your query is vulnerable to SQL Injection. When accepting user input you should avoid concatenating it to your query, instead use Prepared Statements and modify your query like this:
$addquery = "INSERT INTO Particulars (Name, Identification_Number, Number, Nationality, Status, Remarks)
VALUES(?,?,?,?,?,?)";
You can then prepare a statement and bind the values from $_POST. This essentially sanitizes user input. Read more about prepared statements here
START OF EDIT
An example of binding the real values to the ? placeholders using PDO:
//First prepare the statemt
$db->prepare("INSERT INTO Particulars (Name, Identification_Number, Number,Nationality, Status, Remarks)
VALUES(?,?,?,?,?,?)";
//Start binding values to placeholders
$db->bindValue(1, $_POST['name']);
$db->bindValue(2, $_POST['Identification_Number'];
$db->bindValue(3, $_POST['Number'];
//Bind the rest of the values in the same way
END OF EDIT
About the id of the last inserted row you will need to run a separate query to get it. So after you run the above query and if insertion is successful you can
run a query like this:
SELECT LAST_INSERT_ID() AS id FROM Pariculars

Related

IF EXISTS MySQL

I'm from a mssql background so it's difficult to get used to MySQL.
I have a table called users_settings. Within this table there are three columns; uid, name, value. Uid is a integer and refers to the user that owns that setting, the name is the name of the setting, the value, well, you guessed it, is the value.
What I'm trying to do is update these settings if it already exists, but if it doesn't, insert a new row.
My current query is as such (Note I'm using prepared statements):
IF EXISTS (SELECT * FROM users_settings WHERE name = ? AND uid = ?) THEN
UPDATE users_settings SET value = ? WHERE name = ? AND uid = ?;
ELSE
INSERT INTO users_settings (uid, name, value) VALUES (?, ?, ?);
END IF;
The issue I'm having is that when I attempt to prepare my statement, it returns false, which therefore suggests that the syntax is incorrect. After looking in to this, it looks like it's a SQL syntax error.
Would anybody be able to point me in the relative direction as to what may be occurring here, and where I may have got my syntax incorrect?
IN MySQL, if as a statement can only used in programming blocks -- stored procedures, functions, and triggers (this is not to be confused with if as a function, which can be used in almost any SQL statement).
You can do what you want in MySQL with a single statement, insert . . . on duplicate key update. For this to work, you need a unique index on name and uid:
create unique index users_settings_name_uid on users_settings(name, uid);
And then:
INSERT INTO users_settings (uid, name, value)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE value = VALUES(value);
There are two ways to fulfill your request in MySQL:
If you want to update an existing row or insert a new one if it does not exist then you should use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO users_settings (uid, `name`, `value`)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`);
This relies on an unique index that contains the columns uid and name. If it does not already exist, you can create it:
ALTER TABLE users_settings
ADD UNIQUE INDEX uid_name (uid, `name`);
You need it anyway because you want a single entry in the table for each user and setting name.
If you want to insert a row in the table and replace (discard) another one that already exists then you can use REPLACE:
REPLACE INTO users_settings (uid, `name`, `value`)
VALUES (?, ?, ?);
The syntax of REPLACE is similar with the one of INSERT (but it does not support ON DUPLICATE KEY UPDATE for obvious reasons). Internally it does a DELETE followed by an INSERT (it is just a shortcut). It discards the existing row (if any) and insert the new one. It also relies on the presence of the above mentioned index (that you have no matter how you update the values in the table).
For your situation both approaches have the same outcome because there is a single column (value) that is updated or replaced. In other situations only one of them is good.
Choose the one that you feel more appropriate for your workflow and your coding style.
INSERT INTO persona_opcion(nPerCodigo,nOpcCodigo,nPerOpcEstado)
SELECT '$codPer','$idOpc',1
FROM persona_opcion
WHERE NOT EXISTS(
SELECT nPerCodigo,nOpcCodigo,nPerOpcEstado
FROM persona_opcion
WHERE nOpcCodigo='$idOpc'
and nPerCodigo='$codPer'
)
LIMIT 1;
enter link description here

INSERT and set a field to copy the newly inserted id

Is it possible to INSERT a row, and simultaneously set one of the fields to contain the inserted row's ID? (the "self" id)
I'm trying to avoid using multiple queries if possible (it would be 3 queries in total otherwhise)
Something like this (but probably not):
INSERT INTO thetable (email, phone, activationkey) VALUES ($email, $phone, CONCAT(THIS_NEW_ID, md5($activation) )
Why would you want to store duplicated data?
You could change your table structure and just run:
INSERT INTO thetable (email, phone, activation_suffix)
VALUES ($email, $phone, md5($activation))
And then you have all the data you need.
You can always concat when you query the table:
SELECT CONCAT(id, activation_suffix) activationkey
FROM thetable
WHERE ...
UPDATE
On second thoughts, do you really need the id as part of the activationkey?
I wouldn't want to give any user the id for their record in my table unless it is hashed/encrypted.

Insert two table rows, then join in relational table by ID

I have a form that takes two names and two email addresses, then a single password.
I am looking to write multiple queries so that the names and emails get inserted in to one table, then the auto-incrementing IDs generated by the database for both of those get inserted into the second table along with the password.
I run one insert query, grab last_insert_id, then run the other and do the same.
As I'm using last_insert_id to grab the auto-incrementing values, is there any way to store both of these as a variable, so that I can easily insert both their relevant IDs into the second table at the same time? Once I use last_insert_id a second time, it seems to lose the first value.
Pointers on methods to use, or a general direction in which to head, would be much appreciated. I like figuring out the exact code to use on my own.
EDIT:
These are my queries, which work fine except the UIDs created are 1 and 2, but inserted in to the second table are IDs 0 and 1. Any idea why?
$your_query = "INSERT INTO MEMBERS (NAME, EMAIL) VALUES ('$your_name', '$your_email')";
$your_id = (mysql_insert_id());
mysql_query($your_query);
$partner_query = "INSERT INTO MEMBERS (NAME, EMAIL) VALUES ('$partner_name', '$partner_email')";
$partner_id = (mysql_insert_id());
mysql_query($partner_query);
$couples_query = "INSERT INTO COUPLES (UID_1, UID_2, PASSWORD, SALT) VALUES ('$your_id', '$partner_id', '$password', '$salt')";
mysql_query($couples_query);
Turns out I had some extra brackets around each mysql_insert_id, and it should have been run after the mysql_query.
$your_query = "INSERT INTO MEMBERS (NAME, EMAIL) VALUES ('$your_name', '$your_email')";
mysql_query($your_query);
$your_id = mysql_insert_id();
$partner_query = "INSERT INTO MEMBERS (NAME, EMAIL) VALUES ('$partner_name', '$partner_email')";
mysql_query($partner_query);
$partner_id = mysql_insert_id();
$couples_query = "INSERT INTO COUPLES (UID_1, UID_2, PASSWORD, SALT) VALUES ('$your_id', '$partner_id', '$password', '$salt')";
mysql_query($couples_query);

Updating a MySQL record with an auto-increment field as PK

I have a MySQL table with an auto-incrementing primary key (UID). The user can bring up a record in this table via a PHP form, where the UID is a $_GET variable. I would like the database to update the chosen record if it exists, but every time the user hits submit, a new record is created. This is what I've tried so far:
//Present the form
$form = $con->prepare("SELECT Name, Date, Time FROM forms WHERE UID = :uid");
$data = array('uid'=>$_GET['uid']);
$form->execute($data);
$row = $form->fetch(PDO::FETCH_ASSOC);
//Write new record to database. If the UID exists, update the record.
INSERT INTO forms (Name, Date, Time) VALUES (:name, :date, :time)
ON DUPLICATE KEY UPDATE Name=VALUES(Name),Date=VALUES(Date),Time=VALUES(Time);
This doesn't work. Do I need another unique key in the table, or am I missing something obvious?
INSERT INTO forms (`Name`, `Date`, `Time`) VALUES (:name, :date, :time)
ON DUPLICATE KEY UPDATE `Name`=:name, `Date`=:date, `Time`=:time;
This should be the query; I removed VALUES() from your code and added backticks and corrected your parameters.
And I recommend you to use backticks around column names so it doesn't get confused with other similar SQL keywords as example.

Insert into 2 tables from 1 form [duplicate]

This question already has answers here:
MySQL Insert into multiple tables? (Database normalization?) [duplicate]
(7 answers)
Closed 9 years ago.
How do I insert from 1 form into 2 tables?
I want to submit into tables: gallery and cat.
This is the code I have for just submitting into gallery. How do I add info to the cat table simultaneously?
$sql = 'INSERT INTO gallery (image_url, image_name, image_description)
VALUES (?, ?, ?)';
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param('sss', $_FILES['upload']['name'], $_POST['image_name'],
$_POST['image_description']);
$OK = $stmt->execute();
}
What do I do with this:
$sql_2 = 'INSERT INTO cat (cat_name) VALUES (?)';
After the code you have above, just initialize a new statement, bind it, and execute. You can use the existing connection ($conn). The $sql and $stmt variables have already done their job by inserting into the first table, so just reset them for the second insert.
... your code as posted above, followed by:
$sql = 'INSERT INTO cat (cat_name) VALUES (?)';
$stmt = $conn->stmt_init();
if ($stmt->prepare($sql)) {
$stmt->bind_param('s', put your cat_name value here);
$OK = $stmt->execute();
}
The important thing to remember is that the second insert is just like the first: you have to initialize it, bind it, and execute it.
You should use transactions as demonstrated here.
No, you can't insert into multiple tables in one MySQL command. You can however use transactions.
BEGIN
INSERT INTO users (username, password)
VALUES('test', 'test')
INSERT INTO profiles (userid, bio, homepage)
VALUES(LAST_INSERT_ID(),'Hello world!', 'http://www.stackoverflow.com');
COMMIT;
Have a look at LAST_INSERT_ID to reuse autoincrement values.
Edit: you said "After all this time trying to figure it out, it still doesn't work. Can't I simply put the just generated ID in a $var and put that $var in all the MySQL commands?"
Let me elaborate: there are 3 possible ways here:
1/ Is the code you see above. This does it all in MySQL, and the LAST_INSERT_ID in the second statement will automatically be the value of the autoincrement-column that was inserted in the first statement.
Unfortunately, when the second statement itself inserts rows in a table with an auto-increment column, the LAST_INSERT_ID will be updated to that of table 2, and not table 1. If you still need that of table 1 afterwards, we will have to store it in a variable. This leads us to ways 2 and 3:
2/ Will stock the LAST_INSERT_ID in a MySQL variable:
A/ INSERT B/ SELECT LAST_INSERT_ID into #mysql_variable_here C/ INSERT INTO table2 (#mysql_variable_here D/ INSERT INTO table3 (#mysql_variable_here ...
3/ Will stock the LAST_INSERT_ID in a php variable (or any language that can connect to a database, of your choice):
A/ INSERT B/ Use your language to retrieve the LAST_INSERT_ID, either by executing that literal statement in MySQL, or using for example php's mysql_insert_id() which does that for you C/ INSERT ()

Categories