PHP Return ID[uniqueidentifier] after sql INSERT - php

Like the title says, I want the id of a row to be returned after INSERT to the database.
I've got 2 functions, one to make a connection to the database:
function db_connect() {
$host = "host";
$user = "user";
$pwd = "pwd";
$database = "db";
$con;
try{
$conn = new PDO( "sqlsrv:Server= ".$host." ; Database = ".$database." ", $user, $pwd);
}
catch(Exception $e){
die(print_r($e));
}
return $conn;
}
And one to insert a new record:
function setTiptile($name,$cols,$rows) {
$connect = db_connect();
$query = "INSERT INTO data(ID, name, cols, rows) VALUES(NEWID(),?,?,?)";
$stmt = $connect->prepare($query);
$stmt->bindValue(1, $name);
$stmt->bindValue(2, $cols);
$stmt->bindValue(3, $rows);
$stmt->execute();
return $connect->lastInsertId('ID'); // This should work, but doesn't, why?
}
I need the last function to return the ID of the inserted row, how should I do this?
EDIT:
Like the title says, the ID is an uniqueidentifier, no idea if that changes things.
EDIT: Ok, apparently I've got to use:$connect->lastInsertId('ID');, but this isn't returning anything at all. What can be the cause of that? The new row ís created in the database.

From the Manual:
Returns the ID of the last inserted row, or the last value from a
sequence object, depending on the underlying driver. For example,
PDO_PGSQL() requires you to specify the name of a sequence object for
the name parameter.
It should be something like:
return $connect->lastInsertId('yourIdColumn');

Use lastInsertId
$conn->lastInsertId();

(My) solution:
The parameter of lastInsertId() has to be the table name instead of the row name. Besides that, the table must have a row with the parameter IDENTITY checked, this is the row which is returned.
That brings to the conclusion that it's impossible to return a uniqueidentifier with lastInsertId() since this cannot have the parameter IDENTITY checked.

why not first do a select newid()
and then use that id in the insert

Related

Unsuccessful Updating table with PHP using Update table Set

I have a table buildtracker connected to a form. I am attempting to edit the data in a particular row and therefore Update the row.
The table consists of these columns: ID key, EnteredBy, INI
$user = 'root';
$pass = '';
$db = 'cl_db';
$conn = new mysqli('localhost', $user, $pass, $db) or die("Something bad happened.");
$rowID = $conn->real_escape_string($_POST['ID']);
$enteredBy = $conn->real_escape_string($_POST['enteredBy']);
$ini = $conn->real_escape_string($_POST['ini']);
$query = "UPDATE buildtracker SET
EnteredBy = '$enteredBy', INI = '$ini'
WHERE ID = '$rowID' ";
$success = $conn->query($query); //insertion above ^ is the column names
if (!$success) {
die("Couldn't enter data: ".$conn->error);
}
return $query;
I'm receiving no new data or updates on the table. What can I do differently to improve upon this?
Thanks!
I don't know in what context this code is, in your application.
But is is [highly] recommended to use prepared statements for protection against any SQL injection attacks, especially direct data from $_POST is used (can be sanitized).
Checking whether query is executed or not in prepared statements is via $stmt->execute().
$user = 'root';
$pass = '';
$db = 'cl_db';
$conn = new mysqli('localhost', $user, $pass, $db) or die("Something bad happened.");
$prepare_query = "UPDATE buildtracker SET EnteredBy=?, INI=? WHERE ID=?";
$success = $conn->query($prepare_query); //insertion above ^ is the column names
if ($stmt = $conn->prepare($query)) {
// Possible data sanitation can be done below
$rowID = ($_POST['ID']);
$enteredBy = ($_POST['enteredBy']);
$ini = ($_POST['ini']);
// bind parameters
$stmt->bind_param('ssi', $enteredBy, $ini, $rowID);
// CHECKING is here: execute query (or die)
// Can check also for ($stmt->affected_rows > 0)
if (!$stmt->execute()){
die("Couldn't enter data: ".$conn->error);
}
return $query;
}
And using PDO instead of MySQLi would probably be better recommended.
As all errors that I create - this was a result of the declaration of my $rowID not pointing the correct html element.
original
$rowID = $conn->real_escape_string($_POST['ID']); // ID is the COLUMN NAME
Working
$rowID = $conn->real_escape_string($_POST['rowID']); //rowID is the DOM element name
Thank you for your comments and answers.
Going to look into implementing Hossam's safer version of preventing injections. I appreciate you all :)

Executing mysqli insert query then immediately selecting ID of new row

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.

PHP MYSQL SELECT Returns NULL

I executing the following code which creates a company_id as a UUID_SHORT in a temporary table.
This company_id will then be used to insert records in multiple tables with the UUID as the primary key. My issue is when I try retrieve the company_id that is $company_id in my code it is null. However if I json_encode ($tempResult) the company_id value is there. What am I doing wrong?
Any help is much appreciated, thank you!
try {
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $db->id, $db->pass); //connect to db
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //error modes
$temp = $conn->prepare('CREATE TEMPORARY TABLE tempId (user_id VARCHAR(17) PRIMARY KEY, company_id VARCHAR(17))');
$temp->execute();
$temp = $conn->prepare('INSERT INTO tempId(user_id, company_id) VALUES(:user_id, UUID_SHORT())');
$temp->bindParam(':user_id', $_SESSION['username'], PDO::PARAM_INT);
$temp->execute();
$temp = $conn->prepare('SELECT company_id FROM tempId WHERE user_id = :user_id ');
$temp->bindParam(':user_id', $_SESSION['username'], PDO::PARAM_INT);
$temp->execute();
$tempResult= $temp->fetchAll(PDO::FETCH_ASSOC);
$company_id = $tempResult->company_id;
// $result[1] =$_SESSION('username');
} catch(PDOException $e) {
$result = $e->getMessage();
}
print json_encode($company_id);
Here:
$tempResult= $temp->fetchAll(PDO::FETCH_ASSOC);
If the fetchAll is successful, then $tempResult will be an array. For debugging, we can verify this using the convenient var_dump, e.g.
var_dump($tempResult);
If $tempResult is an array, I'm wondering about this expression:
$tempResult->company_id
What does that return? What do you expect that to return? Why?
EDIT: I know better than to answer a question with a question, or three questions.
However, I can't (in good conscience) bring myself to giving an "answer" to the problem with OP code...
at least not without (figuratively) scratching my head wondering about the actual SQL being used in the code.
What is the purpose of the TEMPORARY TABLE? Why is there an INSERT to it? Why is the UNSIGNED BIGINT datatype (returned by UUID_SHORT() function) being cast to a VARCHAR(17)? Is there some reason we want to lop off 1 or 2 digits when the function returns 18 or 19 decimal digits?
If the intent of this block of code is to return a value from MySQL UUID_SHORT() function, I'm not understanding why we need more than one statement. Obviously, there's something I'm missing, why this wouldn't suffice:
try {
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $db->id, $db->pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sth = $conn->prepare('SELECT UUID_SHORT() AS company_id');
$sth->execute();
$company_id = $sth->fetchColumn();
} catch(PDOException $e) {
//var_dump($e->getMessage);
} finally {
if(isset($sth)){ $sth->close(); }
if(isset($conn)){ $conn->close(); }
}
(An application wouldn't churn database connections like this; there would either be a connection pool, or the connection would be passed in to this routine.)
Not sure, but as soon as fetchAll returns array, your code:
$company_id = $tempResult->company_id;
is invalid, you should:
$company_id = $tempResult[0]['company_id'];
or
$tempResult= $temp->fetch(PDO::FETCH_ASSOC);
$company_id = $tempResult['company_id'];

Issues reading arrays from mysql database when using PDO in php

I have the following code set to read and output a specific row from a database based on the criteria in the query statement below. When I try to log the output in console, however, I am only able to get one value and while it DOES exist in the database (as a key attribute), it is from the first row every time. I am not getting a row that matches the SQL criteria. Any ideas?
function getLoginInfo($email,$password){
global $db_user, $db_password, $db_host, $db_name;
if (isValidLogin($email,$password)){
$dbconn = connectToDB($db_user, $db_password, $db_host, $db_name);
$userInfoQuery = $dbconn->prepare("Select * from (Users as U inner join RegisteredUsers as R on U.UID = R.UID) where email = :email");
$userInfoQuery->execute(array(":email"=> 'derp#gmail.com'));
$results = $userInfoQuery->fetch(PDO::FETCH_ASSOC);
echo $results; //will return data in the form ["col1"=>rowdata,"col2"=>rowdata,..."colX"=>rowdata]
}
else{
return false;
}
}
You need to use a loop to fetch all the rows returned by your query:
while( $results = $userInfoQuery->fetch(PDO::FETCH_ASSOC) ) {
echo $results;
}
The documentation for the PDOStatement::fetch function says that the function "Fetches the next row from a result set", so it only returns one row. If the PDOStatement::fetchAll functions that will return the full result set.

This PDO statement is returning an integer instead of a string

In a class, I have some PDO:
$userFName = 'userFName';
include('dbconnect.php'); // Normally I'd store the db connect script outside of webroot
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password);
$stmt = $pdo->prepare('SELECT userFName FROM Users WHERE username = :uname AND password = :pword AND roleID = 1');
$stmt->bindParam(':uname', $this->user->username);
$stmt->bindParam(':pword', $this->user->password);
$stmt->bindColumn(4, $userFName, PDO::PARAM_STR);
$stmt->execute();
$familiar = $stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $familiar;
It's returning the ID in the first column instead of the VARCHAR contents in the 4th column. Any idea why?
When using PDO::FETCH_BOUND with fetch(), the method will not return a result record. Instead the value of the column should be available in the variable you have bound using $stmt->bindColumn() earlier.
So change your code to:
$stmt->bindColumn(1, $userFName, PDO::PARAM_STR);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $userFName; // <-- use the bound variable
However you won't need that bindColumn() call. You could simplify the code as this:
$stmt->execute();
$row = $stmt->fetch(); // uses PDO::FETCH_ASSOC by default
$this->user->firstName = $row['FName'];
There is too much code in your class. And one fault. To send a distinct query to get just one property from database, creating a distinct connection for this is a dead overkill.
Connection have to be moved away unconditionally and you must think of getting ALL user data with one query.
Proper code
function __construct($pdo) {
$this->pdo = $pdo;
// Normally you should include somewhere in a bootstrap file
// not in the application class
// and instantiate PDO in that bootstrap as well
// and only PASS already created instance to the class
}
function getUserFName() {
$sql = 'SELECT * FROM Users WHERE username = ? AND password = ? AND roleID = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute(array($this->user->username,$this->user->password));
return $stmt->fetchColumn();
}

Categories