$SQL = "INSERT INTO primarySkills (primaryName) VALUES $surveySQL";
$result = mysql_query($SQL) or die ('Cannot execute query...'.$SQL);
$surveyID = mysql_insert_id($result);
The above code will enter the table data correctly (primaryID, primaryName) but not return the id generated using mysql_insert_id(). Please let me know why the id is not returned?
What is really odd is that I use this function twice before in the same script for different tables and it works there. I double checked that primaryID is auto_increment and a primary key.
Blessings!
Stop using mysql functions
However the problem in your case could be primaryID is not a autoincrement and probably also not a primary key. For mysql_insert_id() to work, there should be a autoincrement column. Also change the query.
$SQL = "INSERT INTO primarySkills (primaryName) VALUES ($surveySQL)";
and try using mysql_insert_id() instead of mysql_insert_id($result).
Here is an example using pdo since MYSQL functions have been removed as of php 7. I did not test your sql command. replace these values:
localhost: your host
3306: your port if different
dbname: the name of your database
root: your username
'': the last parameter is your password.
<?php
$conn = new PDO('mysql:host=localhost:3306;dbname=testdb', 'root', '');
$conn->SetAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$SQL = "INSERT INTO primarySkills (primaryName) VALUES (:test)";
$insert = $conn->prepare($sql);
$insert->bindValue(":test", $surveySQL, PDO::PARAM_STR);
$insert->execute();
$last_insert_id = $conn->lastInsertId();
?>
When you have completed testing and are ready to go into production, go ahead and remove this line of code:
$conn->SetAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Hope this helps.
Related
I wrote an Install File for my own CMS which I'm working atm. I changed the SQL statements to make it a bit saver but now nothing works and I can't figure out why...
I change my code from:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Connection error to database');
}
$query = "CREATE DATABASE IF NOT EXISTS $db_name;";
$ergebnis = mysqli_query($db, $abfrage);
to:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = "CREATE DATABASE IF NOT EXISTS ?;";
$stmt->bind_param('s', $db_name);
$stmt = $db->prepare($query);
$stmt->execute();
I even tried:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = mysqli_prepare "CREATE DATABASE IF NOT EXISTS ?;";
mysqli_stmt_bind_param($query, 's', $db_name);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
last one added me a database but with the ? as name...
I hoped some one here can help me with that.
Not every SQL statement supports prepared statements. And CREATE DATABASE is one of them.
So, as a general rule, you are supposed to choose the database/table name from the white list.
In your specific case, however, when a user is apparently a database owner, there is not much point in protecting them from SQL injection as they apparently has the database password and can run any SQL statement much more convenient way. So you changed the code for nought. Just revert it back to the regular query() call.
I would only add backticks around the table name so it would always make a correct identifier name. And also may be add a regex validation just in order to avoid a human error.
I've been spending a couple of hours trying to write mysqli queries to insert a new row in a database (with a primary key ID) and then select the ID of the new row. My code as it currently is:
<?php
include('connectionData.php');
$conn = mysqli_connect($server, $user, $pass, $dbname, $port)
or die('Connection error');
if(isset($_POST['submit'])) {
$pnum = $_POST['pnum'];
$phone_insert_text = "INSERT INTO `voterdatabase`.`phone` (`pnum`) VALUES (?)";
$phone_insert_query = $conn->prepare($phone_insert_text);
$phone_insert_query->bind_param('s', $pnum);
$phone_insert_query->execute();
$phone_select_text = "SELECT phone_id FROM voterdatabase.phone WHERE pnum=?";
$phone_select_query = $conn->prepare($phone_select_text);
$phone_select_query->bind_param('s', $pnum);
$phone_select_query->execute();
$phone_select_query->bind_result($phone_id);
echo $phone_id;
?>
$phone_insert_query executes without issue. But $phone_select_query doesn't appear to run at all, as echo $phone_id; has no effect. What might be going on here? I'm able to run the query directly in MySQLWorkbench.
Note that I previously tried doing this in one query using SELECT LAST_INSERT_ID();, but mysqli fails to execute any query containing that.
Please try this
$lastInsertID= mysqli_insert_id($conn);
Use insert_id property:
<?php
include('connectionData.php');
$conn = mysqli_connect($server, $user, $pass, $dbname, $port)
or die('Connection error');
if(isset($_POST['submit'])) {
$pnum = $_POST['pnum'];
$phone_insert_text = "INSERT INTO `voterdatabase`.`phone` (`pnum`) VALUES (?)";
$phone_insert_query = $conn->prepare($phone_insert_text);
$phone_insert_query->bind_param('s', $pnum);
$phone_insert_query->execute();
$phone_id = $conn->insert_id;
echo $phone_id;
?>
If you wish to be able to use the available functions to get the last inserted id, like mysqli_insert_id(), your table must have an AUTO_INCREMENT column. If not you will not get the id.
Also, even if you have the required columns, this will require two calls. To get around this, what you could do is something like create a stored procedure to do your insert for you and return the inserted id from the procedure.
I've been using mysql and mysqli in the past, but am starting a new project, so wanted to go back to OOP with PDO-mysql .. however, it doesn't want to work:
$dbh = new PDO('mysql:host='.$host.';dbname='.$database, $username, $password);
if(isset($_POST["name"]) && isset($_POST["password"]))
{
$pwdHasher = new PasswordHash(8, FALSE);
$hash = $pwdHasher->HashPassword($_POST["password"]);
//$insert = $dbh->prepare('insert into users (username,password) values ("?","?")');
$insert = $pdo->prepare("insert into users (username,password) values (?,?)");
$insert->bindParam(1,$_POST["name"]);
$insert->bindParam(2,$hash);
$insert->execute();
echo "Registration Success!";
}
edit: The above code works if I change the code from the commented line to the non-commented (i.e. single quote to double quotes) However, this doesn't work later:
$query = $pdo->prepare("select * from users where username = ?");
$query->bindParam(1,$_POST["name"]);
$result = $query->execute()
Ok, you've found the answer to your first question.
For the second one it would be
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
called right after connect.
it will tell you what's going wrong with your query.
error_reporting(E_ALL);
also always helps with such errors like misspelled variables ($pdo is not $dbh for example)
If you want to use ? for placeholders, you are supposed to send an array to the execute-method matching the positions of the question marks. $insert->execute(array('value1', 'value2'));
You could however use named placeholders .. WHERE x = :myxvalue and use $insert->bindValue(':myxvalue', 'thevalue', PDO::PARAM_STR);
Also, please have a look at the difference between bindParam and bindValue
The answer to this question is simple and embarrassing:
I need to change the single quotes surrounding the sql statement being prepared to double quotes (and remove the double quotes where the '?' mark is.
change:
$insert = $dbh->prepare('insert into users (username,password) values ("?","?")');
to
$insert = $dbh->prepare("insert into users (username,password) values (?,?)");
and everything works.
Under other circumstances I might be tempted to use
$result = mssql_query("INSERT INTO table (fields) VALUES (data);
SELECT CAST(scope_identity() AS int)");
but as I will be inserting user-submitted data, I want to continue to use PDO, which returns an empty array.
Unfortunately, I'm running PHP on a Linux server and using dblib to interface with Microsoft SQL Server, which doesn't support PDO::lastInsertID().
Please help!
Update to include code example
Here's the code I'm using: col1 is a field of type int identity and col2 is a datetime with a default of getdate().
// Connect to db with PDO
$pdo = new PDO( 'dblib:host=' . $host . ';dbname=' . $database . ';', $username, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) );
// Connect to db with MSSQL
$sql = mssql_connect( $host, $username, $password );
mssql_select_db( $database, $sql );
// Create SQL statement
$query = "INSERT INTO [table] ( col3, col4, col5 )
VALUES ( 'str1', 'str2', 'str3' );
SELECT SCOPE_IDENTITY() AS theID;";
// Run with MSSQL
echo "Using MSSQL...\n";
$result = mssql_query( $query );
$the_id = mssql_result( $result, 0, 'theID' );
echo "Query OK. Returned ID is " . $the_id . "\n";
// Run with PDO
echo "\nUsing PDO...\n";
$stmt = $pdo->query( $query );
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );
print_r( $result );
And this is what was displayed:
Using MSSQL...
Query OK. Returned ID is 149
Using PDO...
Array
(
)
I would love to find out that I'd done something stupid, rather than come up against a horrible dead end :)
You've got a few choices:
SELECT ##IDENTITY - return the last ID created by actions of the current connection, regardless of table/scope
SELECT SCOPE_IDENTITY() - last ID produced by the current connection, in scope, regardless of table
SELECT IDENT_CURRENT('name_of_table'); - last ID produced on that table, regardless of table/scope/connection
Of the three, SCOPE_IDENTITY() is the best candidate.
Maybe you are getting two rowsets returned. Try adding SET NOCOUNT ON; to eliminate the INSERT's rowset, or use $stmt->nextRowset if your driver supports it.
The 'id' field of my table auto increases when I insert a row. I want to insert a row and then get that ID.
I would do it just as I said it, but is there a way I can do it without worrying about the time between inserting the row and getting the id?
I know I can query the database for the row that matches the information that was entered, but there is a high change there will be duplicates, with the only difference being the id.
$link = mysqli_connect('127.0.0.1', 'my_user', 'my_pass', 'my_db');
mysqli_query($link, "INSERT INTO mytable (1, 2, 3, 'blah')");
$id = mysqli_insert_id($link);
See mysqli_insert_id().
Whatever you do, don't insert and then do a "SELECT MAX(id) FROM mytable". Like you say, it's a race condition and there's no need. mysqli_insert_id() already has this functionality.
Another way would be to run both queries in one go, and using MySQL's LAST_INSERT_ID() method, where both tables get modified at once (and PHP does not need any ID), like:
mysqli_query($link, "INSERT INTO my_user_table ...;
INSERT INTO my_other_table (`user_id`) VALUES (LAST_INSERT_ID())");
Note that Each connection keeps track of ID separately (so, conflicts are prevented already).
The MySQL function LAST_INSERT_ID() does just what you need: it retrieves the id that was inserted during this session. So it is safe to use, even if there are other processes (other people calling the exact same script, for example) inserting values into the same table.
The PHP function mysql_insert_id() does the same as calling SELECT LAST_INSERT_ID() with mysql_query().
As to PHP's website, mysql_insert_id is now deprecated and we must use either PDO or MySQLi (See #Luke's answer for MySQLi). To do this with PDO, proceed as following:
$db = new PDO('mysql:dbname=database;host=localhost', 'user', 'pass');
$statement = $db->prepare('INSERT INTO people(name, city) VALUES(:name, :city)');
$statement->execute([':name' => 'Bob', ':city' => 'Montreal']);
echo $db->lastInsertId();
As #NaturalBornCamper said, mysql_insert_id is now deprecated and should not be used. The options are now to use either PDO or mysqli. NaturalBornCamper explained PDO in his answer, so I'll show how to do it with MySQLi (MySQL Improved) using mysqli_insert_id.
// First, connect to your database with the usual info...
$db = new mysqli($hostname, $username, $password, $databaseName);
// Let's assume we have a table called 'people' which has a column
// called 'people_id' which is the PK and is auto-incremented...
$db->query("INSERT INTO people (people_name) VALUES ('Mr. X')");
// We've now entered in a new row, which has automatically been
// given a new people_id. We can get it simply with:
$lastInsertedPeopleId = $db->insert_id;
// OR
$lastInsertedPeopleId = mysqli_insert_id($db);
Check out the PHP documentation for more examples: http://php.net/manual/en/mysqli.insert-id.php
I just want to add a small detail concerning lastInsertId();
When entering more than one row at the time, it does not return the last Id, but the first Id of the collection of last inserts.
Consider the following example
$sql = 'INSERT INTO my_table (varNumb,userid) VALUES
(1, :userid),
(2, :userid)';
$sql->addNewNames = $db->prepare($sql);
addNewNames->execute(array(':userid' => $userid));
echo $db->lastInsertId();
What happens here is that I push in my_table two new rows. The id of the table is auto-increment. Here, for the same user, I add two rows with a different varNumb.
The echoed value at the end will be equal to the id of the row where varNumb=1, which means not the id of the last row, but the id of the first row that was added in the last request.
An example.
$query_new = "INSERT INTO students(courseid, coursename) VALUES ('', ?)";
$query_new = $databaseConnection->prepare($query_new);
$query_new->bind_param('s', $_POST['coursename']);
$query_new->execute();
$course_id = $query_new->insert_id;
$query_new->close();
The code line $course_id = $query_new->insert_id; will display the ID of the last inserted row.
Hope this helps.
Try like this you can get the answer:
<?php
$con=mysqli_connect("localhost","root","","new");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_query($con,"INSERT INTO new values('nameuser','2015-09-12')");
// Print auto-generated id
echo "New record has id: " . mysqli_insert_id($con);
mysqli_close($con);
?>
Have a look at following links:
http://www.w3schools.com/php/func_mysqli_insert_id.asp
http://php.net/manual/en/function.mysql-insert-id.php
Also please have a note that this extension was deprecated in PHP 5.5 and removed in PHP 7.0
I found an answer in the above link http://php.net/manual/en/function.mysql-insert-id.php
The answer is:
mysql_query("INSERT INTO tablename (columnname) values ('$value')");
echo $Id=mysql_insert_id();
Try this... it worked for me!
$sql = "INSERT INTO tablename (row_name) VALUES('$row_value')";
if (mysqli_query($conn, $sql)) {
$last_id = mysqli_insert_id($conn);
$msg1 = "New record created successfully. Last inserted ID is: " . $last_id;
} else {
$msg_error = "Error: " . $sql . "<br>" . mysqli_error($conn);
}
Another possible answer will be:
When you define the table, with the columns and data it'll have. The column id can have the property AUTO_INCREMENT.
By this method, you don't have to worry about the id, it'll be made automatically.
For example (taken from w3schools )
CREATE TABLE Persons
(
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
PRIMARY KEY (ID)
)
Hope this will be helpful for someone.
Edit: This is only the part where you define how to generate an automatic ID, to obtain it after created, the previous answers before are right.