Integer inserting as 0 instead of NULL - php

When I insert a NULL into a MYSQL INTEGER field via a PHP prepared statement it inserts as 0.
I have searched for similar questions and have update my code but am still having the problem.
In my code, if a text box sends an empty string to PHP; PHP converts it to NULL ie.
$v3 = (strlen($v3)<1 ) ? NULL : $v3;
As an example, a result in the UNIT column could be NULL.
The prepare statement
$stmt = $mysqli->prepare("INSERT INTO address ( `PERSON`, `TYPE`, `UNIT`, `STREET_NUM`, `STREET`, `STREET_TYPE`, `SUBURB`, `STATE` ) VALUES (?,?,?,?,?,?,?,?)"));
Bind the parameter as an integer
$stmt->bind_param('isiissss',$p, $add_type[$a], $unit[$a], $street_num[$a], $street_name[$a], $street_type[$a], $suburb[$a], $state[$a]);
In MYSQL, address.unit is NULLABLE and has no default value.
If I insert directly into the table and omit a value for the unit column; NULL is stored. Which I expected.
I suspect that the bind_param function changes NULL to 0 if the datatype for the column is specified as 'i' (integer), because NULLs passed to VARCHAR columns are stored as NULL.
Am I correct and if so how should I pass a NULL to the integer column?

To simplify my question (and because I didn't think it would be relevant) I omitted that the values where passing through a $mysqli->real_escape_string function and after some testing I found that it converts a NULL to an empty string
$test = "";
$test = (strlen($test)<1 ) ? NULL : $test;
var_dump($test); // null
echo "<br>";
$test = $mysqli->real_escape_string($test);
var_dump($test); // string '' (length=0)
This does not solve my problem but it does answer this question

Related

How to insert a null value for INT in database?

I am not using HTML form to get values for this query. I am just inserting a second query once user creates a specific record. However, the second query is not inserting '0' unless I change it to VARCHAR. Others are working fine except for number.
$null = null;
$query2="insert into npi_program2 (prodID,prodName,TPM,scheme,phases,status,number,date,remarkProg)
values('$prodID','$prodName','$null','$null','$null', 0 ,DATE_FORMAT(NOW(),'%b-%d-%Y'),'$null')";
$res1=$db->query($query2);
0 is not equal to null. 0 is false. To insert null in the database, you should pass NULL as a value.
$query2="insert into npi_program2 (prodID,prodName,TPM,scheme,phases,status,number,date,remarkProg)
values($prodID,$prodName,NULL,NULL,NULL, 0 ,DATE_FORMAT(NOW(),'%b-%d-%Y'),NULL)";
$res1=$db->query($query2)

MySQL Where clause values 0 and 1 not working correctly

The situation
In table I have columns configurated as ENUM('0','1'). I have select query build with PDO like this example
$value = isset($_POST['value']) ? $_POST['value'] : (isset($_GET["value"]) ? $_GET["value"] : null);
$sql = $pdo->prepare("SELECT * FROM tablename WHERE column = :value");
$sql->bindValue(':value', $_POST['value']); // post contains 0 or 1
$sql->execute();
The problem
When printing the results, value 1 is working normally. But when using value 0, all rows are showing including rows with value 1.
Following query is working normally when trying it in HeidiSQL, but it's not with PHP. What's wrong? SELECT * FROM tablename WHERE column = '0'
I noticed that PHP thinks $_POST['value'] is unset when its value is zero. I'm using isset()
Trying to solve the problem
No effect either if using $_GET['value'] and url like index.php?value=0
Tried following, not working $sql->bindValue(':value', '0'); // post contains 0 or 1
I changed column type to TINYINT(1) - no effect. When looking for zero, all are showing.
Set PDO bindValue() $data_type to PDO::PARAM_BOOL, not working
Try this:
$value = empty($_POST['value']) ? '0' : '1' ;
$sql = $pdo->prepare("SELECT * FROM tablename WHERE column = :value");
$sql->bindValue(':value', $value, PDO::PARAM_STR); // post contains 0 or 1
$sql->execute();
Good luck!
An ENUM is a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table creation time.
An enumeration value must be a quoted string literal; it may not be an expression, even one that evaluates to a string value.
The index value of the empty string error value is 0. This means that
you can use the following SELECT statement to find rows into which
invalid ENUM values were assigned:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
So use single quote to consider the zero(0) as string.

bindParam and NULL int values

I am using bindParam to set values for a MySQL insert. The column in question is an INT (11). It has a default of NULL and null is allowed. However, using bindParam it always receives a 0. I have confirmed that my $_POST['value'] is indeed null.
if(isset($_POST['value'])){
$stmt = $db->prepare("INSERT INTO table (column) VALUES (:column)");
$stmt->bindParam(':column',$_POST['value'], PDO::PARAM_INT);
$stmt->execute();
}
It keeps inserting a '0' instead of NULL if the POST value was ''.
You should be matching the complete case (Answer and type) with === (Read More)
Which most likely means that your value is not null like you presume it is.
Ensure it is by checking (pseudo code below):
if(VALUE !=== NULL) {
value = null
}
But you get the idea there? If not just comment :-)
And as aldanux mentioned in his comment, you have to wrap the column in backticks as it is a reserved word:
INSERT INTO table (`column`) VALUES (:column)

SELECT statement for NOT NULL values is returning NULL values.

I have PHP code that gets values using a $_POST and then inserts into a DB. All of the fields are input based except the CU00, etc. because it denotes a primary key .
Now suppose user enters just one row:
$ sql="INSERT INTO weekly
VALUES
('$_POST[uactual]','$_POST[utarget]','CU001','$a1','$_POST[ucomment]',NOW())
,('$_POST[uactual2]','$_POST[utarget2]','CU002','$a2','$_POST[ucomment2]',NOW())
,('$_POST[uactual3]','$_POST[utarget3]','CU003','$a3','$_POST[ucomment3]',NOW())
,('$_POST[dactual]','$_POST[dtarget]','CD001','$b1','$_POST[dcomment]',NOW())
,('$_POST[dactual2]','$_POST[dtarget2]','CD002','$b2','$_POST[dcomment2]',NOW())
,('$_POST[dactual3]','$_POST[dtarget3]','CD003','$b3','$_POST[dcomment3]',NOW())
,('$_POST[iactual]','$_POST[itarget]','CI001','$c1','$_POST[icomment]',NOW())
,('$_POST[iactual2]','$_POST[itarget2]','CI002','$c2','$_POST[icomment2]',NOW())
,('$_POST[iactual3]','$_POST[itarget3]','CI003','$c3','$_POST[icomment3]',NOW())
,('$_POST[ractual]','$_POST[rtarget]','CR001','$d1','$_POST[rcomment]',NOW())
,('$_POST[ractual2]','$_POST[rtarget2]','CR002','$d2','$_POST[rcomment2]',NOW())
,('$_POST[ractual3]','$_POST[rtarget3]','CR003','$d3','$_POST[rcomment3]',NOW())";
SQL TABLE
ACTUAL|TARGET|KEY |SIGNAL |TIME
NULL NULL CU001 NULL 00:00
NULL NULL CU002 NULL 00:00
NULL NULL CU003 NULL 00:00
NULL NULL CU004 NULL 00:00
100 200 CU005 300 00:00
I want to do a select where only the rows with signal are selected. But when I do a:
SELECT *
FROM TABLE
WHERE
'signal' IS NOT NULL
I get all the rows returned. It is as if there are no NULL values in my table .
SELECT *
FROM TABLE
WHERE
signal IS NOT NULL
'signal' is just string literal which is indeed NOT NULL.
You possibly meant ` instead of '.
You are putting empty strings into the DB.
Do this:
(empty($_POST['uactual']) ? 'NULL' : '\'' . $_POST['uactual'] . '\'')
For all $_POST variables. Then you can be sure that there will be NULL values.
Please don't do this: $_POST[uactual]! PHP will search for defined val first! Do $_POST['uactual'] Use ' always!
Also, your select is wrong. ` not '. If you don't believe do such query:
SELECT 'signal' FROM TABLE
This is correct:
SELECT `signal` FROM TABLE or
SELECT signal FROM TABLE
This will return you string 'signal', not the `signal` column.
WHERE
'signal' IS NOT NULL
This will always be true! This why it returns whole data. You made 2 mistakes then :] In inserting and in selecting data.
You are not inserting any NULLs. You are inserting empty strings at best.
Also, you should use some validation of your inputs.

MySQL int column allows null but enters null as zero

I've looked around and have noticed a few people have had the same problem but their oversight doesn't seem to apply here.
I have a PHP function to add an array of values into a table. It first checks whether the values are empty and if so replaces them with NULL, in order to place a null in the table field. Each fields that I'm placing null into allows for null yet places a 0 there instead.
Here's some code:
public static function AddGame($array, $tId)
{
global $db; // Bring DB into scope
// Get IDs from particular names
$locId = $array['fLocation'];
// Ensure empty values are SQL null
$hTeamId = "'{$array['fHomeTeam']}'";
$vTeamId = "'{$array['fVisitTeam']}'";
$hScore = "'{$array['fHomeScore']}'";
$vScore = "'{$array['fVisitScore']}'";
$hHoldFor = "'{$array['fHomeHoldFor']}'";
$vHoldFor = "'{$array['fVisitHoldFor']}'";
// Prepare row for insertion
$row = "'','$tId','$locId',$hTeamId,$vTeamId,'{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
$stmt = $db->prepare("INSERT INTO `game` VALUES($row)");
if($stmt->execute()) return true;
else return false;
}
I've debugged this function at various lines and have dumped the $row string and it shows this, which is expected:
'','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL','NULL'
Yet when I check the table text type fields literally have the value NULL which is not what I want and also int fields show as 0. If I leave the values blank or as PHP's null then text fields show as empty (or properly null as I'd like) yet the ints still show as 0.
I expect this is only caused due to the way I insert the values indirectly.
Here is the SHOW CREATE TABLE game
CREATE TABLE `game` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tId` int(11) NOT NULL,
`Lid` int(11) NOT NULL,
`hTeamId` int(11) DEFAULT NULL,
`vTeamId` int(11) DEFAULT NULL,
`date` text NOT NULL,
`time` text NOT NULL,
`hScore` int(11) DEFAULT NULL,
`vScore` int(11) DEFAULT NULL,
`type` text NOT NULL,
`hHoldFor` text,
`vHoldFor` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=latin1
UPDATE:
INSERT INTO `game` VALUES('','1','1','','','10/09/12','9:30AM','','','pool','winner of pool A','winner of pool B')
You are physically setting the value of the wanted NULL columns to a string of 'NULL'
NULL != 'NULL'
If you set your table structure for those columns to NULL, you can omit them from your query and they will automatically be NULL on insert.
Do this instead:
if(!empty($hHoldFor)) $hHoldFor = $array['fHomeHoldFor'];
Update
I was looking further into your example and there is a second point of failure.
$row = ... ",'$hHoldFor','$vHoldFor'";
The above line, if you set $hHoldFor = NULL, will insert quotes around NULL, turning it back into a string of NULL.
Try this:
if(!empty($hHoldFor)) $hHoldFor = "'{$array['fHomeHoldFor']}'";
...
$row = ... ",$hHoldFor,$vHoldFor";
This removes the single quotes around this value in the QUERY string and adds them to the variable itself.
Update 2
Here is an SQLFiddle using your schema. It returns NULL for NULL columns. Can you do an echo "INSERT INTOgameVALUES($row)"; and post the output? The issue is PHP is converting the NULL to 'NULL' still somewhere. This will help us get to the bottom of it.
Update 3
The issue is just as thought. Your PHP is inserting a blank string, '', into your database, which is not a NULL value. NULL is of a type, '' is a string with no length.
INSERT INTO `game` VALUES('','1','1','','','10/09/12','9:30AM','','','pool','winner of pool A','winner of pool B')
Try this:
public static function AddGame($array, $tId)
{
global $db; // Bring DB into scope
// Get IDs from particular names
$locId = $array['fLocation'];
// Ensure empty values are SQL null
$hTeamId = (strlen($array['fHomeTeam']) != 0 ? "'{$array['fHomeTeam']}'" : 'NULL');
$vTeamId = (strlen($array['fVisitTeam']) != 0 ? "'{$array['fVisitTeam']}'" : 'NULL');
$hScore = (strlen($array['fHomeScore']) != 0 ? "'{$array['fHomeScore']}'" : 'NULL');
$vScore = (strlen($array['fVisitScore']) != 0 ? "'{$array['fVisitScore']}'" : 'NULL');
$hHoldFor = (strlen($array['fHomeHoldFor']) != 0 ? "'{$array['fHomeHoldFor']}'" : 'NULL');
$vHoldFor = (strlen($array['fVisitHoldFor']) != 0 ? "'{$array['fVisitHoldFor']}'" : 'NULL');
// Prepare row for insertion
$row = "'','$tId','$locId',$hTeamId,$vTeamId,{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
$stmt = $db->prepare("INSERT INTO `game` VALUES($row)");
if($stmt->execute()) return true;
else return false;
}
You can't insert 'NULL'. Remove the single quotes around NULL.
Your string
'','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL','NULL'
Should look like
'','1','1','21','21','10/10/12','10:30AM',NULL,NULL,'pool',NULL,NULL
You should also define a column list whenever making an INSERT (ie. INSERT INTO table (col1, col2) VALUES ...)
Edit 1
I would recommend looking through your SHOW CREATE TABLE tbl_name
Edit 2
After testing this, I would still say the problem is with how you're inserting the data.
(18,1,1,21,21,'10/10/12','10:30AM',NULL,NULL,'pool',NULL,NULL)
Works.
('18','1','1','21','21','10/10/12','10:30AM','NULL','NULL','pool','NULL','NULL')
Does not work: Incorrect integer value: 'NULL' for column 'hScore' at row 1:
Edit 3
Here is an improved version of your class:
public static function AddGame($array, $tId)
{
global $db; // Bring DB into scope
// Get IDs from particular names
$locId = $array['fLocation'];
// Ensure empty values are SQL null
$hTeamId = empty($array['fHomeTeam']) ? 'NULL' : "'" . $array['fHomeTeam'] . "'";
$vTeamId = empty($array['fVisitTeam']) ? 'NULL' : "'" . $array['fVisitTeam'] . "'";
$hScore = empty($array['fHomeScore']) ? 'NULL' : "'" . $array['fHomeScore'] . "'";
$vScore = empty($array['fVisitScore']) ? 'NULL' : "'" . $array['fVisitScore'] . "'";
$hHoldFor = empty($array['fHomeHoldFor']) ? 'NULL' : "'" . $array['fHomeHoldFor'] . "'";
$vHoldFor = empty($array['fVisitHoldFor']) ? 'NULL' : "'" . $array['fVisitHoldFor'] . "'";
// Prepare row for insertion
$row = "$tId,$locId,$hTeamId,$vTeamId,'{$array['fDate']}','{$array['fTime']}',$hScore,$vScore,'{$array['fGameType']}',$hHoldFor,$vHoldFor";
$stmt = $db->prepare("INSERT INTO game (tId, Lid, hTeamId, vTeamId, date, time, hScore, vScore, type, hHoldFor, vHoldFor) VALUES($row)");
if($stmt->execute()) return true;
else return false;
}
Non-NULL values will be encased in quotes, otherwise they are assigned NULL. I've also defined the column list for INSERT and excluded id, as it's an AUTO_INCREMENT column.
Does you column allows NULL values? Check the DDL again maybe you have set the DEFAULT VALUE to zero.
When you try to insert null value in a column, don not wrap it with single quote. Example
INSERT INTO tableName (colName, ColNameB) VALUES (1, NULL)
In my case i had to display three situations: Case-empty, Case-yes and Case-no. I planned to use null, one and zero. But the null was being saved always as 0. The column i was working accepted null entries but all my nulls was being saved as zeros.
My solution, was considering Case-empty as zero, Case-yes as the number one and case-no as the number two. It is a workaround but solved the problem.

Categories