I'm having the problem that the query I'm passing through a function is duplicating me the rows. Before, instead of the statement->execute(array()), I had PARAM_STR working for each value. However, it started to give me problems. This is the code that is duplicating me the rows.
static public function mdlIngresarUsuario($datos){
$statement = Conexion::conectar()->prepare("INSERT INTO usuarios (id, nombre, usuario, password, rol, estado) VALUES (null, :nombre, :usuario, :password, :rol, :estado)");
$statement->execute(array(
':nombre' => $datos['nombre'],
':usuario' => $datos['usuario'],
':password' => $datos['password'],
':rol' => $datos['rol'],
':estado' => 0
));
if ($statement->execute()) {
return "ok";
} else {
return "error";
}
}
You're executing the statement twice:
$statement->execute(array(
':nombre' => $datos['nombre'],
':usuario' => $datos['usuario'],
':password' => $datos['password'],
':rol' => $datos['rol'],
':estado' => 0
));
and then in the condition of the if statement:
if ($statement->execute()) {
return "ok";
}
Just log the return of the first "execute", and use that as the condition:
$success = $statement->execute(array(
':nombre' => $datos['nombre'],
':usuario' => $datos['usuario'],
':password' => $datos['password'],
':rol' => $datos['rol'],
':estado' => 0
));
if( $success ) { return "ok"; }
This is happening because you call $statement->execute twice, once where you 'create' it and once in the if statement. You should assign the value of the first execute to a variable and use that variable in the if statement, like:
public static function mdlIngresarUsuario($datos)
{
$statement = Conexion::conectar()->prepare("INSERT INTO usuarios (id, nombre, usuario, password, rol, estado) VALUES (null, :nombre, :usuario, :password, :rol, :estado)");
$result = $statement->execute(array(
':nombre' => $datos['nombre'],
':usuario' => $datos['usuario'],
':password' => $datos['password'],
':rol' => $datos['rol'],
':estado' => 0
));
if ($result) {
return "ok";
} else {
return "error";
}
}
Related
I am using this php code to insert new record in database. The problem is that if ($query) sometimes returns true and when I check the table, there is no new record. Why is it not inserting the record? and why is it returning true when it should return false in case of failing?
public function insertUserMileage($alias, $address, $distance, $city,
$latitude, $longitude, $id) {
$sql = 'INSERT INTO user_mileage (user_id, alias, address, distance,
city, lat, lng) VALUES (:id, :alias, :address, :distance, :city,
:latitude, :longitude)';
$query = $this->conn->prepare($sql);
$query->execute(array(':id' => $id, ':alias' => $alias,
':address' => $address, ':distance' => $distance, ':city' => $city,
':latitude' => $latitude, ':longitude' => $longitude));
if ($query) {
return true; // Insert success
} else {
return false; // Insert fail
}
}
You need to check the return value of execute:
$result = $query->execute(array(':id' => $id, ':alias' => $alias,
':address' => $address, ':distance' => $distance, ':city' => $city,
':latitude' => $latitude, ':longitude' => $longitude));
if ($result) {
return true; // Insert success
} else {
return false; // Insert fail
}
To put it briefly, I'm looking for a way to do a redirect after a successful PDO insert. Here is what I have so far.
Function for redirecting
<?php
function redirect_to($new_location) {
header("Location: " . $new_location);
exit;
}
?>
PDO INSERT
Please note, I've trimmed some code in my example below to make it easier to read.
try {
$sql = "INSERT INTO location_info (`department`, `participant`, `activity`, `location`, `rec_injuries`, `rec_injuries_timeframe`, `non_rec_injuries` )
VALUES (:department, :participant, :activity, :location, :rec_injuries, :rec_injuries_timeframe, :non_rec_injuries, :non_rec_injuries_timeframe, '{$id}')";
$stmt = $db->prepare($sql);
for($i = 0, $l = count($_POST["department_name"]); $i < $l; $i++) {
$loc_info = array(':department' => $_POST["department_name"][$i],
':rec_injuries_timeframe' => $_POST["injury_time_frame"][$i],
':non_rec_injuries' => $_POST["non_rec_injuries"][$i],
':non_rec_injuries_timeframe' => $_POST["non_rec_injury_timeframe"][$i],
':competitor' => $_POST["competitor"][$i],
':cost_per_pair' => $_POST["cost_per_pair"][$i],
':usage_rate' => $_POST["usage_rate"][$i],
':leakage' => $_POST["leakage"][$i],
':cost_of_productivity' => $_POST["cost_of_productivity"][$i],
':non_rec_impact' => $_POST["non_rec_impact"][$i],
':non_rec_sprain' => $_POST["non_rec_sprain"][$i],
':non_rec_puncture' => $_POST["non_rec_puncture"][$i],
':non_rec_dermatitis' => $_POST["non_rec_dermatitis"][$i],
':non_rec_infection' => $_POST["non_rec_infection"][$i],
':non_rec_burns' => $_POST["non_rec_burns"][$i],
':non_rec_cuts' => $_POST["non_rec_cuts"][$i],
':rec_impact' => $_POST["impact"][$i],
':rec_sprain' => $_POST["sprain"][$i],
':rec_puncture' => $_POST["puncture"][$i],
':rec_dermatitis' => $_POST["dermatitis"][$i],
':rec_infection' => $_POST["infection"][$i],
':rec_burns' => $_POST["burns"][$i],
':rec_cuts' => $_POST["cuts"][$i],
':condition' => $_POST["condition"][$i] );
$stmt->execute($loc_info);
}
if ($stmt->execute()) {
redirect_to($_SERVER["DOCUMENT_ROOT"]."/testing/tim/results.php");
}
}
catch (Exception $e) {
$error = $e->getMessage();
print "<b>error:</b> " . $error;
}
You'll see that I have an if statement for the redirect with if ($stmt->execute()) {
redirect_to($_SERVER["DOCUMENT_ROOT"]."/testing/tim/results.php");
Where am I going wrong?
Where am I going wrong?
When you are adding A LOT of useless code.
Here goes the FULL code you need (save for the trimmed array):
$sql = "INSERT INTO location_info (`department`, `participant`, `activity`, `location`, `rec_injuries`, `rec_injuries_timeframe`, `non_rec_injuries` )
VALUES (:department, :participant, :activity, :location, :rec_injuries, :rec_injuries_timeframe, :non_rec_injuries, :non_rec_injuries_timeframe, '{$id}')";
$stmt = $db->prepare($sql);
for($i = 0, $l = count($_POST["department_name"]); $i < $l; $i++) {
$loc_info = array(
':department' => $_POST["department_name"][$i],
':condition' => $_POST["condition"][$i]
);
$stmt->execute($loc_info);
}
redirect_to("/testing/tim/results.php");
This is all.
This code will redirect if all executes will be executed successfully.
You have a bit of a structure issue here...
If you're wanting to execute an indeterminate number of queries, then redirect after all queries have been executed successfully, then you need to track all the statement executions and errors.
If you want to throw an error the first time you have one, and stop inserting, then you just check the return result of the execute function and throw an error if it fails:
$sql = "INSERT INTO location_info (`department`, `participant`, `activity`, `location`, `rec_injuries`, `rec_injuries_timeframe`, `non_rec_injuries` )
VALUES (:department, :participant, :activity, :location, :rec_injuries, :rec_injuries_timeframe, :non_rec_injuries, :non_rec_injuries_timeframe, '{$id}')";
$stmt = $db->prepare($sql);
$errors = array();
for($i = 0, $l = count($_POST["department_name"]); $i < $l; $i++) {
$loc_info = array(':department' => $_POST["department_name"][$i],
':rec_injuries_timeframe' => $_POST["injury_time_frame"][$i],
':non_rec_injuries' => $_POST["non_rec_injuries"][$i],
':non_rec_injuries_timeframe' => $_POST["non_rec_injury_timeframe"][$i],
':competitor' => $_POST["competitor"][$i],
':cost_per_pair' => $_POST["cost_per_pair"][$i],
':usage_rate' => $_POST["usage_rate"][$i],
':leakage' => $_POST["leakage"][$i],
':cost_of_productivity' => $_POST["cost_of_productivity"][$i],
':non_rec_impact' => $_POST["non_rec_impact"][$i],
':non_rec_sprain' => $_POST["non_rec_sprain"][$i],
':non_rec_puncture' => $_POST["non_rec_puncture"][$i],
':non_rec_dermatitis' => $_POST["non_rec_dermatitis"][$i],
':non_rec_infection' => $_POST["non_rec_infection"][$i],
':non_rec_burns' => $_POST["non_rec_burns"][$i],
':non_rec_cuts' => $_POST["non_rec_cuts"][$i],
':rec_impact' => $_POST["impact"][$i],
':rec_sprain' => $_POST["sprain"][$i],
':rec_puncture' => $_POST["puncture"][$i],
':rec_dermatitis' => $_POST["dermatitis"][$i],
':rec_infection' => $_POST["infection"][$i],
':rec_burns' => $_POST["burns"][$i],
':rec_cuts' => $_POST["cuts"][$i],
':condition' => $_POST["condition"][$i] );
if(!$stmt->execute($loc_info)){
$errors[] = $e->getMessage();
// un-comment if you want to stop on error:
// print "<b>error:</b> " . $e->getMessage();
// die();
};
}
if(count($errors)){
foreach($errors as $error){
print "<b>error:</b> " . $e->getMessage()."<br/>";
}
} else {
redirect_to($_SERVER["DOCUMENT_ROOT"]."/testing/tim/results.php");
}
I'm trying to execute two INSERT statements and I need the last inserted id to do so. I've tried $question_id = $dbh->lastInsertId();, but it doesn't work. Now I'm executing an additional SELECT LAST_INSERT_ID() statement, but that doesn't work either. I keep getting this error: SQLSTATE[HY093]: Invalid parameter number: parameter was not defined, which occurs because $question_id is empty because selecting the last insert id doesn't seem to work.
Here's my code:
public function add_question($user_id, $group_id, $title, $caption, $datetime, $status) {
// Add user to database
try {
$dbh = new DBHandler();
$sql =
"INSERT INTO question(
user_id,
group_id,
title,
caption,
created_date_time,
question_status
)
VALUES(
:user_id,
:group_id,
:title,
:caption,
:created_date_time,
:question_status
)";
$stmt = $dbh->get_instance()->prepare($sql);
$stmt->execute(
array(
':user_id' => $user_id,
':group_id' => $group_id,
':title' => $title,
':caption' => $caption,
':created_date_time' => $datetime,
':status' => $status
)
);
//$question_id = $dbh->lastInsertId();
$sql= "SELECT LAST_INSERT_ID() AS question_id";
$stmt = $dbh->get_instance()->prepare($sql);
$stmt->execute();
// Resultset
$result = $stmt->fetchAll();
foreach($result AS $question_id_row) {
$question_id = $question_id_row['question_id'];
}
$sql =
"INSERT INTO notification(
n_question_id,
n_question_user_id,
n_question_group_id,
n_question_title
)
VALUES(
:n_question_id,
:n_question_user_id,
:n_question_group_id,
:n_question_title
)";
$stmt = $dbh->get_instance()->prepare($sql);
$stmt->execute(
array(
':n_question_id' => $question_id,
':n_question_user_id' => $user_id,
':n_question_group_id' => $group_id,
':n_question_title' => $title
)
);
echo 'Question added!';
}
catch(PDOException $e) {
echo $e->getMessage();
}
}
Your query fails with invalid number of parameter and parameter was not defined because you define this parameter
:question_status
but you bind
':status' => $status
change
$stmt->execute(
array(
':user_id' => $user_id,
':group_id' => $group_id,
':title' => $title,
':caption' => $caption,
':created_date_time' => $datetime,
':question_status' => $status //here
)
);
and it will work
If I run my function edit_profile() without any parameter, then empty strings are written in DB. If $input['email'] is empty for example, I'd like UPDATE not to update this column.
I tried to do:
SET email = IF(LENGTH(:email)=0, email, :email),
It didn't work, I'm not sure how to do same as above with PDO.
function edit_profile($input) {
//
$user_id = 1;
//
try {
//
$conn = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USERNAME, DB_PASSWORD);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare('UPDATE users SET
email = :email,
password = :password,
name_surname = :name_surname,
age = :age,
sex = :sex,
education = :education,
avatar = :avatar
WHERE id = :id');
$stmt->execute(array(
':id' => $user_id,
':email' => $input['email'],
':password' => $input['password'],
':name_surname' => $input['name_surname'],
':age' => $input['age'],
':sex' => $input['sex'],
':education' => $input['education'],
':avatar' => $input['avatar']
));
echo $stmt->rowCount(); // 1
//
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
//
}
edit_profile();
Try
UPDATE users SET
email = COALESCE(NULLIF(:email, ''),email),
password = :password,
name_surname = :name_surname,
age = :age,
sex = :sex,
education = :education,
avatar = :avatar
WHERE id = :id
I'm basically trying to use COALESCE (http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce) to use :email only if not null. If it's null, use the old email.
In case :email is empty string and not simply NULL, I've added NULLIF to convert the empty string to NULL ;)
SET email = IF(LENGTH(:email1)=0, email, :email2)
$stmt->execute(array(
':id' => $user_id,
':email1' => $input['email'],
':email2' => $input['email'],
':password' => $input['password'],
':name_surname' => $input['name_surname'],
':age' => $input['age'],
':sex' => $input['sex'],
':education' => $input['education'],
':avatar' => $input['avatar']
));
Why do I not get a result in the following code and num_rows returns 0?
Here is my code:
function get_user($user_id) {// This function give some data from table user with user_id
try {
$connection = start_service();
$user_id = sanitize_string($user_id);
$stmt = $connection->prepare(
"SELECT user_id, name, lname, gender, password, avatar, bdate, user_group_id, status, signup_date, last_signin
FROM user
WHERE user_id = ?
");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$stmt->bind_result($user_id, $name, $lname, $gender, $password, $avatar, $bdate, $user_group_id, $status, $signup_date, $last_signin);
if($stmt->num_rows){
while($stmt->fetch()) {
array_push($result, array(
"user_id" => $user_id,
"name" => $name,
"lname" => $lname,
"gender" => $gender,
"password" => $password,
"avatar" => $avatar,
"bdate" => $bdate,
"user_group_id" => $user_group_id,
"status" => $status,
"signup_date" => $signup_date,
"last_signin" => $last_signin
));
}
} else {
$result = false;
}
print $stmt->num_rows;
$stmt->close();
end_service();
} catch (exception $e) {
end_service_error();
echo $e->getMessage(), "\n";
throw $e;
}
return $result;
}
Where is the problem and what must I do to fix it?
I think you need to call mysqli_stmt_store_result() before calling mysqli_stmt_num_rows().
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_id, $name, $lname, $gender, $password, $avatar, $bdate, $user_group_id, $status, $signup_date, $last_signin);
if($stmt->num_rows){
...
}