SQL, how to get the automated ID from the previous INSERT? - php

I am using PHP and SQL and trying to insert user data into two tables upon registration. First in the user_table and second into the character_table. I'm using an automatically generating user_id to link the tables and need to get the value of the user_id from the first INSERT (into user_table) then add it to a column in the character_table.
I tried a few methods and here is where I ended ($username, $email, $password and $character are defined above);
$sql = "INSERT INTO
user_table (id, username, email, password)
VALUES ('NULL', '".$username."', '".$email."', '".$password."')
INSERT INTO
character_table (name, id)
VALUES ('".$character."', 'LAST_INSERT_ID()')";"
I want "id" from user_table to match with "id" inserted into character_table.
When I run the above, nothing seems to be happening. Previous attempts I always ended with id = 0. What is the correct way I can get the ID from the first INSERT?

Run your statements seperately. You run your insertion into your user_table, then grab the id then run your insertion into your character_table
You can grab the id using mysql_insert_id after running the insert. Note that on the php webpage detailing the mysql_insert_id function that it is deprecated as is all mysql* functions. Which leads to...
For the love of everything holy don't concatenate your variables directly to your INSERT statement. Switch to mysqli* functions or PDO if you haven't already and use prepared statements (parameterizing the query). If you build an application using mysql it means you are not parameterizing your queries which means you are at a huge risk for a sql injection attack.
If/when you switch over to mysqli or PDO functions you will find an equivalent mysqli_insert_id() (or PDO::lastInsertID()) function

Related

SQL Update a whole table with new data

I am running a query every 15 minutes to retrieve new data from an API and store this data in my database.
So every 15 minutes I would like to store the new data in the table and get rid of the all old data in that table.
I am currently using the following method:
$sql = "DELETE FROM self_user_follower
INSERT INTO self_user_follower (username, profile_picture, full_name, user_id, last_updated)
VALUES (:query_username, :query_profile_picture, :query_full_name, :query_user_id, :query_last_updated)";
But it gives me the following error:
Array
(
[0] => 42000
[1] => 1064
[2] => You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO self_user_follower (username, profile_picture, full_name, user_id, l' at line 2
)
query_error
Is this the best way to do it or is there a nicer and cleaner way to do this?
If you want to put two SQL queries into one statement string, you have to
separate them with a semi-colon (;)
use the function mysqli_multi_query which supports multiple queries.
Unless you have a very good reason, modify your code so that it executes each query separately. MySQLi offers transaction support if you need that.*
The reason why you need a separate function is instructive; as mentioned in the docs:
An extra API call is used for multiple statements to reduce the likeliness of accidental SQL injection attacks. An attacker may try to add statements such as ; DROP DATABASE mysql or ; SELECT SLEEP(999). If the attacker succeeds in adding SQL to the statement string but mysqli_multi_query is not used, the server will not execute the second, injected and malicious SQL statement.
*: Actually, I'm not even sure the multi_query will execute both queries in the same transaction - I'm just guessing for your reason to use a multi-query.
Multiple statements should be terminated by semi colon
Try this
$sql = "DELETE FROM self_user_follower;
INSERT INTO self_user_follower
(username, profile_picture, full_name, user_id, last_updated)
VALUES (:query_username, :query_profile_picture, :query_full_name, :query_user_id,
:query_last_updated)";

i need to insert values into two different table with single query

How do I join these two queries and execute them as a single query to insert values in two tables:
$sql = mysql_real_escape_string('INSERT INTO admin_export(datetime, product_name, item_code,quantity,subject,export_no) VALUES').implode(',', $row_data);
$sql2 = "insert into `itflower_exportno` (admin_exportno) values('$exportno1')";
You need to separate your two INSERT statements with a semicolon into the single variable.
This(mysql_*) extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. Switching to PreparedStatements is even more better to ward off SQL Injection attacks !
You can however use transactions as following example.
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;
What you have in the code are two different inserts.
MySQL doesn't allow for multiple inserts to be run in the same query so you will have to do one first and then the other.
However you can insert multiple rows in the same table in just one query, basically you are restricted to do all the insert you want in one table at a time.
You can't do this.
If you want to do it because you are afraid of the integrity of the data, use transaction .
Second, use suitable transaction isolation level, to ensure that data are reading correctly.

Using the data of the index column I just added

I was just reading about PDO::lastInsertId from the PHP documentation, but after some tests I reallized I absolutelly suck at PHP xD and I should investigate more about classes and static methods and more to even understand where to put that code.
Anyway, I'm not actually trying to know the last Inserted Id, I want to get the Index value of the last inserted row of MySQL table. My Index column is called "id" and is set to auto increment everytime I add a new row, yet, when I delete a row the number doesn't update, so the value in the row called "id" may not allways be the same as the row number.
Here is the code that inserts a new row.
<?php
require('conexion.php');
$name=$_POST['name'];
$email=$_POST['email'];
$pass=$_POST['pass'];
$localidad=$_POST['localidad'];
$saldo=$_POST['saldo'];
$slastupdate=$_POST['slastupdate'];
$query="INSERT INTO usuarios (name, email, pass, localidad, saldo, slastupdate) VALUES ('$name','$email','$pass','$localidad','$saldo','$slastupdate')";
$resultado=$mysqli->query($query);
?>
Update: For now on, I'm using another query to get the last inserted's row Id... In my case using PDO is not necessary since I'm developing a private app, and there's no risk of mysql injections
require_once "../php/new_mysql.php";
$query="INSERT INTO clientes (gira, localidad, nombre, email, proxivisi, saldo) VALUES ('$gira', '$localidad', '$nombre', '$email', '$proxivisi', '$saldo')";
$agregar=$mysql->query($query) or die(mysql_error());
$querygetid=$mysql->query("SELECT id, proxivisi FROM clientes WHERE nombre='$nombre' AND email='$email'");
$getid=$querygetid->fetch_assoc();
$id=$getid['id'];
#FranCano use #user to notify us of your reply.
Your first problem is you seem to be using mysqli, not PDO in the above code. mysqli and PDO are different APIs to run MySQL queries and don't share functions. PDO::lastInsertId will give you the auto increment value of the last inserted row.
Start with PDO::__construct() to see how to start a PDO instance and connect to a database. Check PDO::query() and the examples listed to see how PDO works. However, PDO::query() is basic and does not protect you from SQL injections. For your above query you should be used prepared statements since you use user input (POST). Prepared statements are started with PDO::prepare(). MySQLi has prepared statements too but they are slightly different.
PDO is object oriented, you can't just call PDO::query() and PDO::lastInsertId(). You create a PDO instance to connect to the database, then you create a PDOStatement object by using prepare(), then you execute (PDOStatement::execute) that PDOStatement object to run the query. Then you can resort to the lastInsertId() on the original PDO object.
If you don't know OOP or object oriented programming then this will all sound pretty confusing so that is where you need to start your reading.
A quick example is:
$pdo = new PDO(..mysql connection information..);
// Create a PDOStatement object
$stmt = $pdo->prepare("INSERT into test ('field1', 'field2') VALUES (?, ?)");
// Execute the prepared statement safely inserting the post variables into the ?'s. This protects against SQL injection attacks.
if ($stmt->execute(array($_POST['value1'], $_POST['value2']))) {
$id = $pdo->lastInsertId();
}

inserting multiple record using single mysql_query possible or not?

I'm working on a site in which I have to insert values in different table. so keeping this need in view, is it possible for me that can I use multiple query in single mysql_query in php or not.
for example:
mysql_query("insert into tableA (e-mail, name) values ('xxx', 'xxx'); insert into tableB (xxx, xxx, xxx) values ('value1','value2','value3')")
I want to run multiple queries in single statement. Please suggest some solution.
No, it is not possible. The obsolete mysql_* API only allows for one query to be executed at a time. To do this you need to use the mysqli API and mysqli_multi_query().
A single MySQL "INSERT" statement can support multiple VALUE tuples if they're for the same table.
mysql_query("insert into tableA (e-mail, name) values ('xxx', 'xxx'), ('yyy','yyy')")
However, what you're trying to do is not possible with the mysql_* functions.
Although the mysqli_* API allows you to run multiple queries at once, I recommend you AGAINST doing that for at least 2 reasons:
It's always a good (actually, great) idea to use prepared statements, for security reasons. Prepared statements can be used with the MySQLi API as well as with PDO.
As you can see from the docs for mysqli_multi_query(), getting errors from that function can be cumbersome. The function, indeed, returns only "false" if the first query fails; to get results for other queries you need to call another function.
In general, why would you need to combine multiple queries together? Eventually, the time you'd save would be minimal.
Instead, if your goal is having more than one query executed together, and having the whole set of queries fail if one fails, you can use transactions (which also can speed up inserts in some cases). Both MySQLi and PDO support transactions: see examples here for PDO http://php.net/manual/en/pdo.transactions.php
PS: in general, it's a good idea to avoid using mysql_* functions entirely, as those APIs are deprecated.
Welcome to PDO:
With PDO am able to do something like:
$sql = "
insert into tableA (e_mail, name) values (:e_mail, :name);
insert into tableB (xxx1, xxx2, xxx3) values (:xxx1, :xxx2, :xxx3)
";
Just have the Query Prepared first then VOILA!!
OR Using the Transaction method:
$con->beginTransaction();
$sql1 = "insert into tableA (e_mail, name) values (:e_mail, :name)";
$sql2 = "insert into tableB (xxx, fff) values (:xxx, :fff)";
$sql3 = "insert into tableC (qqq, bbb) values (:qqq, :bbb)";
$con->commit();

how to insert data from primary key column to foregin key

i am inserting data from a form i want when i will insert data so the first column primary id which is using in second column as a foreign key should be increased
i have tried this code but not working
first table code
$this->db->query("insert into af_ads (ad_title,ad_pic,ad_description)
values ('$title','$filepath','$description')");
second table code
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category','ad_id')");
NOTE: i want to insert ad_id into ad_id_fk
Try this:
// Your first query
$this->db->query("insert into af_ads(ad_id, ad_title, ad_pic, ad_description)
values ('', '$title', '$filepath', '$description')");
$ad_id = $this->db->insert_id(); // This returns the id that is automatically assigned to that record
// Use the id as foreign key in your second insert query
$this->db->query("insert into af_category (cat_type,ad_id_fk)
values ('$category', $ad_id)");
MySQL provides the LAST_INSERT_ID function as way to retrieve the value generated for an AUTO_INCREMENT column from the immediately preceding INSERT statement.
A lot of client libraries make this conveniently avaiable (e.g. PDO lastInsertId function.)
(I'm not familiar with CodeIgniter or ActiveRecord, so I can't speak to how that's made available.
Your code looks like it's using the PDO interface... but I'm not sure about that.
# either we need to check return from functions for errors
# or we can have PDO do the checks and throw an exception
$this->db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
# attempt insert which will generate AUTO_INCREMENT value
$this->db->query("INSERT (ad_id, ... ) VALUES (NULL, ...)");
# if previous insert successfully inserted a row (or rows)
$ad_id = $this->db->lastInsertId();
You really need to check whether the previous insert was successful or not. If you aren't going to code that check yourself, then PDO does provide a mechanism that performs this checking automatically, and will throw an exception if a MySQL error occurs.
I've avoided copying your original code, which looks like it's vulnerable to SQL Injection. If you're using PDO, you can make effective use of prepared statements with bind placeholders, rather than including values in the SQL text.

Categories