Insert NULL values to MySql records using MySqli - php

My page sends using ajax data to a php script. one of the vars that the script gets is: $product_disc
now a small test that I have done inside the script clearly revealed that $product_disc is null. the test:
if ($product_disc == null)
{$test="null";}
else {$test="not null";}
I make my code return $test to the ajax calling procedure:
$return_array['success'] = array ('test' => $test);
And using Firebug I see that the ajax response has: "test":"null"
So i conclude that $product_disc is of value: null
Now, inside my script I'm using the following code to insert data to MySql DB:
$stmt = mysqli_prepare($link, "INSERT INTO set_products (id,discount) VALUES (NULL , ?)");
mysqli_stmt_bind_param($stmt, "i", $product_disc);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
The query is being executed, but the value that was inserted is 0 and not NULL!
Only when I explicitly added: $product_disc=null; before the MySqli statements, the value that was inserted was NULL.
Why is that? What's the different between a null and a null? I followed this answer in stackoverflow hoping that i could easily insert NULLs but then came this problem...
Thank you!
PS #stackoverflow team - Your spell checking dictionary doesn't recognize the word stackoverflow!

You prepare product_disc as integer, null is not an integer. It is converted to 0.
While preparing as a string, would definitely fix your issue, it defeats the purpose of preparing a mysql statement. Consider this solution:
mysqli_stmt_bind_param($stmt, $product_disc==null?'s':'i', $product_disc);

Related

Attempting to perform an update/insert query using php prepared statement and mysqli but to no avail

I'm trying to execute the following code as a prepared statement using PHP:
private function prepQuery(){
$this->prepSQL = $this->con->prepare('
IF EXIST(SELECT * FROM tablename WHERE reference=?)
UPDATE tablename
SET
column1=?,
column2=?,
column3=?
WHERE reference=?
ELSE
INSERT INTO tablename(
column1,
column2,
column3,
column4
) VALUES(?, ?, ?, ?);
');}
The code executes in an object context where the connection object is a private field variable in the class. The function should initialize the $prepSQL field variable to be an object but I get the following error:
Fatal error: Uncaught Error: Call to a member function bind_param() on boolean
The purpose of the code is to read a file which gets updated regularly(The file size and field data is out of my control so using prepared statements would be the best choice for speed and security). The code should check if the record exist in the database and if so, update it to contain the changes made. Else, insert the new row from the file into the database.
However, it doesn't complete as it says that the $prepSQL variable is a boolean and cannot call the bind_param method on it.
I tried executing the sql manually and that works fine. If I use a normal insert statement in the code, it works fine. But when run as is below it doesn't work. I'm really not sure what I'm doing wrong here.
Your query contains an error. And you are trying to run bind_param on something that didn't work.
You are probably doing:
$this->prepSQL = $this->con->prepare('...');
$this->prepSQL->bind_param()
The prepare() method can return false and you should check for that. As for why it returns false, perhaps the table name or column names (in SELECT or WHERE clause) are not correct?
Also, consider use of something like $this->db->conn->error_list to examine errors that occurred parsing the SQL. (I'll occasionally echo the actual SQL statement strings and paste into phpMyAdmin to test, too, but there's definitely something failing there.)
That said while not an answer to the actual question DO listen to what other comments said:
Using INSERT INTO ... ON DUPLICATE KEY UPDATE ... is much easier than your IF ELSE statement.
https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html

PHP MySQL Prepared Statement returning no result

I have an issue with my prepared statement that is being sent through PHP to my database. Can someone tell me why the below statement does not return the result? I'll just describe what I want it to do, what its doing and the code.
I have data being sent through a form that is ready to be inserted into one of my tables but I need to get a value from another table to insert.
I used to the following SELECT statement to get the tripNo based off the data entered. This query works on MySQL Workbench and returns the correct result, but it doesn't work on my php form. The result is null when I echo $tripNo.
Code:
$destination=$_POST['destination'];
$dateOfSail=$_POST['dateOfSail'];
$db = createConnection();
$sql="select tripNo from TripDB where dateOfSail=? AND destination=?;";
$stmt=$db->prepare($sql);
$stmt->bind_param("ss",$dateOfSail,$destination);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($tripNo);
echo "tripNo: $tripNo"; //returns null value
There are no errors being reported so I am not sure where to investigate next as I have looked at the prepared statements examples.
Also, I have a side question. Is the method bad practice on getting a value in order to insert to a table?
after the bind_result you have to perform fetch:
while ($stmt->fetch()) {
echo "tripNo: $tripNo<br />";
}

PHP pdo bindParam type management

This is the post form:
$funcname->name= htmlentities($_POST['name']);
$funcname->insert();
this will be the function insert on class funcname which will insert the data to column named name
$this->conn->beginTransaction();
$stmt = $this->conn->prepare("INSERT INTO nameTBL (name) values (:name)";
$stmt->bindParam(':name', $this->name, PDO::PARAM_INT);
if ($stmt->execute()) {
$this->conn->commit(); //This will save your changes
$this->conn->exec('UNLOCK TABLES ' . self::$table_name);
header('Location: ../');
exit();
} else {
$this->conn->rollBack(); //This will undo your changes
$this->conn->exec('UNLOCK TABLES ' . self::$table_name);
header('Location: ../');
exit();
}
Now question is i have set PDO::PARAM_INT which should not allow characters but only integer why i am able to post text to database(table)?
is there any how i can highly restrict the data type on bindParam here.
thanks in advance.
You've got several mistakes in your code.
However, let's go over what the types PDO::PARAM_INT, PDO::PARAM_STR and PDO::PARAM_NULL are telling MySQL to do.
Those values are telling PDO how to treat the input, not to disallow input. If you send text, but the column is int then MySQL will attempt to coerce the data into int. It won't tell you "you entered abcd but expected value was integer". You must do this check on your own before passing data to PDO.
Now onto other problems:
Don't use bindParam. bindParam accepts the value by reference. This is intended for when you invoke stored procedures and variable is supposed to be modified based on procedure's output. Use bindValue. If you tried to do the following with bindParam, it wouldn't work and you'd get an error:
$stmt->bindParam(':my_column', 1, PDO::PARAM_INT); // It fails and yields an error
Don't lock tables. You're already using transactions, no need to lock the table, MySQL handles concurrency and access for you.
Bottom line - perform validation before using PDO for inserting. PDO helps you clean the input based on connection information (among other things). It won't perform validation.

Proper way to bind an array to prepared statements?

This has probably been asked a handful of times already, but I'm having a hard time understanding how to bind an array to a mysqli prepared statement.
What I'm trying to do is query for a list of user id's in a message thread, and then insert into the messages table so the user can be notified of a new message reply.
This is what I've tried:
//now check which users are in the message thread
$stmt2 = $mysqli->prepare("SELECT DISTINCT user_id_2
FROM uc_user_messages
WHERE thread_id = ?");
$stmt2->bind_param("i", $this->thread_id_clean);
$stmt2->bind_result($user_2_id);
$stmt2->execute();
$stmt3 = $mysqli->prepare("
INSERT INTO `users`.`uc_user_messages`(
`id` ,
`message_id` ,
`user_id_2` ,
`read` ,
`thread_id`
)
VALUES (
NULL , ?, ?, ?, ?
);
");
//now insert the message into the user_messages table so the user can be notified of a new message
while ($row = $stmt2->fetch()){
$stmt3->bind_param("iiii", $inserted_id, $user_2_id, $read, $this->thread_id_clean );
$stmt3->execute();
}
What am I doing wrong? I've tried putting the prepared statement inside the loop too, but I keep on getting this error:
Fatal error: Call to a member function bind_param() on a non-object
I've also ran the query manually with test data, so I know it's the loop that's causing the value not to bind correctly.
Edit: I should add that the select query is working fine and that it's the insert query that is causing an error.
Fatal error: Call to a member function bind_param() on a non-object
This means that $stmt2 or $stmt3 is not an object. The prepare() function returns false if there was any problem parsing or validating the query. But false->bind_param() is just not going to work.
This is a very common mistake made by many MySQL developers. The solution is you have to check that prepare() returned success and not false.
Example:
$stmt2 = $mysqli->prepare("...");
if ($stmt2 === false) {
// do something to report $mysqli->error, and return
}
Also see http://php.net/manual/en/mysqli.error.php
once a var has been bound to your prep statement, it stays bound.
That means that cou call bind_param only once (outside of the loop), and then just repeat the two-step-loop "change var values / execute".
php.net: Check section #3 INSERT prepared once, executed multiple times
Also be sure that the quotes you used for db and table names don't interfere with PHPs backtick operator. (In that specific case, you can ommit those quotes.)
You are not checking for the errors. Do it the way explained here: https://stackoverflow.com/a/15447204/285587
Most likely the error is something like "Commands out of sync" one. You have to use store_result() on the first query to avoid that. Strangely, Bill has a perfect answer which is first on google search - you can refer to it for the details.
I only can't get which arrays you are talking about.

Cant get stored procedure resultset via PDO PHP

I cant seem to get any output from my stored procedure (MYSQL) using PDO (PHP).
Stored procedure:
CREATE PROCEDURE getUserId(serviceId VARCHAR(64), serviceInput VARCHAR(32))
BEGIN
SELECT id FROM users WHERE servid = serviceId AND service = serviceInput;
END
PHP code:
$mysqlConn = mysqlPDOLogin();
$stmt = $mysqlConn->prepare("CALL getUserId(?,?);");
$stmt->bindParam(1, $USERID);
$stmt->bindParam(2, $USERPROVIDER);
$stmt->execute();
$returned_a = $stmt->fetch();
echo $returned_a['id'];
It doesnt get anything back. Ive copied the basic select code out of the stored procedure and used it directly in the PHP code and it works, but cant get it to work via stored procedure.
Any help would be appreciated...
You're not doing any apparent error checking. Prepare(), bindParam() and execute() will all alert you to errors by either returning false or throwing an exception, depending on the error reporting mode PDO is in.
I'm going to assume you're in "return false" mode.
You need to check that $stmt is a PDOStatement object, that the bindParam statements didn't return false and that execute didn't return false. If any of them did then you need to use errorCode() and errorInfo() to find out what went wrong.
Also, it looks somewhat excessive to me to be using a stored procedure for what is basically a simple query. Why not just do the following?
$stmt = mysqlConn->prepare ('SELECT id FROM users WHERE servid = ? AND service = ?');

Categories