I have a table in a CakePHP 3 application called downloads which has a column called master. The field type is set to TINYINT(1)
I can find any records where downloads.master == 1 like this:
$query = $this->Downloads->find()->where(['master' => true]);
But Cake won't let me query for ones where downloads.master !== 1. None of these work, and all return an empty array/object when the query is executed:
$query = $this->Downloads->find()->where(['master' => false]);
$query = $this->Downloads->find()->where(['master' => 0]);
$query = $this->Downloads->find()->where(['master' => null]);
$query = $this->Downloads->find()->where(['master' => '']);
What do you use as the condition to make this possible? My thinking was that it should be false since that's the opposite to true, but as with most things in CakePHP 3 they like to make it more complicated than necessary...
I've examined the records in my table using phpMyAdmin and there are indeed both records where master == 1 and master == null so it's not a case of there's zero results to return.
A column being NULL is not the same as being 0 (ie false-ish from the point of view of the ORM in case of a boolean-ish column type). If you want to compare against NULL, then you must issue a query with IS NULL, which is a SQL/DBMS requirement, not a CakePHP requirement.
CakePHP however requires you to be specific about what you want to do, as passing null does not neccesarily have to mean that you want to compare against SQL NULL, depending on the context.
Long story short, use the IS operator:
where(['master IS' => null])
Similarly use IS NOT for a negated condition. You can also pass user input as the value, the ORM will test the value and convert the IS and IS NOT operators into = and != respectively in case a non-null value is being passed.
See also
Cookbook > Database Access & ORM > Query Builder > Automatic IS NULL Creation
I am having a form with an appending table which goes on appending the values entered in the form to the table and as I click the Save button, the entire record set goes to the table...
The Controller page:-
function invoiceEntry(){
$ref_invoice_no=$_POST['ref_invoice_no'];
$entry_date=$_POST['entry_date'];
$store_name=$_POST['store_name'];
$store_name=empty($_POST['store_name']) ? NULL : $_POST['store_name'];
$no_packages=$_POST['no_packages'];
$net_weight_each=$_POST['net_weight_each'];
$total_net_qty=$_POST['total_net_qty'];
$obj=new Sales();
foreach ($ref_invoice_no as $key => $value) {
$obj->addInvoice($ref_invoice_no[$key],$entry_date[$key],$store_name[$key],$no_packages[$key],$net_weight_each[$key],$total_net_qty[$key]);
}
}
The Model page:-
function addInvoice($ref_invoice_no,$fregno,$entry_date,$catalogue_type,$store_name,$category,$grade,$pack_type,$manufacture_date,$full_half,$sample_allowed,$no_packages,$net_weight_each,$total_net_qty){
$conn=new Connection();
$sql="INSERT INTO invoice (ref_invoice_no,fac_reg_no,date_of_entry,exestate_mainsale,stores_code,category_code,grade_code,packing_code,date_of_manufacture,full_half,sample_allowed,no_of_packages,net_weight_each,total_net_qty) VALUES('$ref_invoice_no','$fregno','$entry_date','$catalogue_type',$store_name,'$category','$grade','$pack_type','$manufacture_date','$full_half','$sample_allowed','$no_packages','$net_weight_each','$total_net_qty')";
echo $sql;
$result=$conn->query($sql);
return $result;
}
I am getting the error as :-
Cannot add or update a child row: a foreign key constraint fails (teabs.invoice, CONSTRAINT invoice_ibfk_2 FOREIGN KEY (stores_code) REFERENCES stores (stores_code))
But if I go and place the query in PHPMyAdmin, it works perfectly as I have set the stores field to accept NULL values.
This is wrong since store_name is an array, and u need to check the indexes. this code is never setting null.
$store_name=empty($_POST['store_name']) ? NULL : $_POST['store_name'];
change it to:
$store_name=$_POST['store_name'];
You need to move that logic into:
$obj->addInvoice($ref_invoice_no[$key],$entry_date[$key],empty($store_name[$key]) ? NULL : $store_name[$key],$no_packages[$key],$net_weight_each[$key],$total_net_qty[$key]);
You can check if this works.
Just a simple function in native php
protected function some_function(){
session_start();
if(!isset($_SESSION['a']))
{
$_SESSION['a'] = 'some value';
return true;
} else {
return $_SESSION['a'];
}
}
on the 1st run, it will return bool(true) and then "some value" as expected.
Applying the same to laravel session,
protected function some_function(){
$a = Session::get('abc');
if(is_null($a)){
Session::put('abc', 'some value');
//return Session::get('abc');
return true;
} else {
return $a;
}
}
By logic, on the 1st run, $a will be null. and then puts "some value" in abc key and returns bool(true) as expected.
However on consequent access, the Session::get('abc') returns null every time. so every attempt returns bool(true).
I assumed may be session wasn't writing properly so i checked with getting the key value right after setting it.
by commenting out the line in the above code, it returns whatever value i put in Session::put('abc'). So there is no error in writing the data.
Problem here is trying to retrieve the value always returns null though i have set after the 1st request.
Am i missing something here?
EDIT
Using database as the driver, The sessions does not get save in database. No error is outputted. Database implementation has been correct with sessions table schema as described in docs.
Try this snippet. Untested, but pretty sure it works.
if(Session::has('abc'))
{
return Session::get('abc');
} else {
Session::put('abc', 'some value');
return true;
}
After going through many forum to solve same issue, I solved it by setting my session driver to database.
'driver' => 'database',
and created table in database
CREATE TABLE `sessions` (
`id` varchar(40) NOT NULL,
`last_activity` int(10) NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Everytime I try to make an insert statement into my dastabase I get a "Incorrect decimal value: 'NULL' for column 'bounty3' at row 1" error. How do I insert a null value into a decimal datatype? Should I just make the default value 0.00?
Incorrect decimal value: '' for column 'bounty3' at row 1 Whole query: INSERT INTO songs (userid, wavURL, mp3URL, genre, songTitle, BPM, insWanted, bounty, insWanted2, bounty2, insWanted3, bounty3, insWanted4, bounty4, insWanted5, bounty5, insWanted6, bounty6, insWanted7, bounty7, insWanted8, bounty8, insWanted9, bounty9, insWanted10, bounty10) VALUES ('12534545', '/audio/wav/jqmrgpfcMichael/135259578210secreason.wav', '/audio/mp3/jqmrgpfcMichael/135259578210secreason.mp3', 'Rock/Funk', 'titlee', '120', 'bass', '20.00', 'guitar', '20.00', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')
I tried this statement with a NULL value too. Here is the error:
Incorrect decimal value: 'NULL' for column 'bounty3' at row 1 Whole query: INSERT INTO songs (userid, wavURL, mp3URL, genre, songTitle, BPM, insWanted, bounty, insWanted2, bounty2, insWanted3, bounty3, insWanted4, bounty4, insWanted5, bounty5, insWanted6, bounty6, insWanted7, bounty7, insWanted8, bounty8, insWanted9, bounty9, insWanted10, bounty10) VALUES ('12534545', '/audio/wav/jqmrgpfcMichael/143922765110secreason.wav', '/audio/mp3/jqmrgpfcMichael/143922765110secreason.mp3', 'Rock/Funk', 'title', '110', 'bass', '110.00', 'guitar', '20.00', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL')
Oh.. you are trying to insert an empty string '' into bounty3. Replace it with NULL. I have also noticed empty strings for other possible numeric values eg bonty4. You should replace all empty strings with NULL for numeric values.
eg: mysql_query("INSERT INTO empty_number,number VALUES(NULL,1)");
EDIT: HEY HEY get the point, you cannot insert NULL to a numeric value as 'NULL' because this is a string, you should insert as NULL without any quotation marks
use blank, not null, if you want the default value.
I just dealt with this issue in MySql 5.1.61.
If the server is in strict mode, you must enter 0 instead of '' for decimal fields. Disabling strict mode allows you to just do '' to populate a null value.
Thanks, it worked using NULL when it comes empty:
$conn->bindParam(':'.$valor, ( $key[0] ? $key[0] : NULL ), PDO::PARAM_STR);
You can run this query to allow NULL values in 'bounty3' field.
ALTER TABLE songs CHANGE bounty3 bounty3 DECIMAL(10,0) NULL;
Make sure the field type allows for NULL values and that the default is NULL.
Then use:
UPDATE table_name SET date_field=IF('$date_value'='',NULL,'$date_value')
This works for inserts or updates.
I have tried using $date_value = NULL and I have even tried unset($date_value) before inserting or updating, and it never worked on my decimal fields. MySQL always converted them to 0.00. The method above was the only solution that worked for me.
Make sure that the field is "nullable" (does not have NOT NULL in its definition)
Make field's default value NULL.
Ex.: price decimal(12,2) DEFAULT NULL
Now, to test it, store some number, then '' (an empty string) into this field — it should become NULL in the end.
The field is most likely numeric. If the field is numeric then only numbers are accepted. Empty string is not accepted
insert into songs (...,bounty3) values(...,'')
neither the NULL string
insert into songs (...,bounty3) values(...,'NULL')
('NULL' which is just a string, nothing to do with the actual NULL value, so 'NULL' si similar to 'HONEY BEE' if you want).
So if the column is numeric then it will only take numbers. However if the column is NULLABLE then it will accept NULL, too. That means your insert must have
insert into songs (...,bounty3) values (..., NULL)
If you push NULL on such a column and the column has a default value then DEFAULT value will be used instead of the NULL you are pushing.
You need to make sure that your database schema allows NULL values for that column. Run describe <tablename>; in your MySQL client to see what the schema for that table is.
If the schema does not allow null then you can use alter table to change the schema. Make sure you don't specify NOT NULL for that column and you should be fine.
Another option is to make sure that in your source data, the empty cells or fields contain 'NULL' before you import them in MySQL. This way, MySQL will recognize these fields as being really NULL, and won't transform them to 0's.
It worked por me when POST data is received:
...
if ($value == '') {$value = '0.0';}
...
I've module and I've update to alter database table, shortly I need to do something like
ALTER TABLE `TABLE` ADD `FIELD` INT UNSIGNED NOT NULL AFTER `SOME_FIELD`
so is there any built in function in Drupal to make this changes I considered db_add_field function didn't work?
Sultan
Using db_add_field()
db_add_field('TABLE', 'FIELD', "VARCHAR( 255 ) NOT NULL DEFAULT '0' AFTER FIELD_2");
The above does not work, for one it leaves out the first argument (the reference to $ret) and the fourth argument will not allow a raw sql query, only a structured array.
What I had to do was this (change hook_update_N to modulename_update_XXXX as per the drupal api documentation of course):
function hook_update_N(&$sandbox) {
// We use update_sql here, instead of db_add_field because we cannot specify
// AFTER in the db_add_field.
$ret = array();
$ret[] = update_sql("ALTER TABLE {table} ADD `FIELD` INT UNSIGNED NOT NULL AFTER `SOME_FIELD`");
return $ret;
}
Hope this helps someone else.