Cannot set the value for an SQL function field. These fields are read only.
Cannot set the value for an SQL function field. These fields are read only.
This question has an accepted answers - jump to answer
This question has an accepted answers - jump to answer
Answers
The error message is correct - Editor's server-side libraries (assuming that is what you are using here) do not support the ability to write a value to an SQL function.
From the information above, one (or more) of those fields must be generated from an SQL function? Can you show me your server-side code?
Thanks,
Allan
Hi Allan,
Thanks, here is the server side:
```
<?php
//SESSION START
if(!isset($_SESSION)) {
session_start();
if(isset($_SESSION['userID'])) {
$userID = $_SESSION['userID'];
} else {
$userID = null;
}
}
$del = $_SESSION['del'];
include("../lib/DataTables.php");
use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Join,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate,
DataTables\Editor\ValidateOptions;
Editor::inst( $db, 'assettype T', 'T.assetTypeID' )
->field(
Field::inst( 'T.assetType' )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Must have a name' )
) ),
Field::inst( 'T.Nomenclature' )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'What are Tags of this equipment labelled as?' )
) ),
Field::inst( 'T.subsystem' )
->options( Options::inst()
->table('system')
->value('systemID')
->label('systemName')
->where( function ($q) {
$q->where( 'systemID', 0, '!=' );
} )
)
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which system is the asset part of?' )
) ),
Field::inst( 'S.systemName' ),
Field::inst( 'T.spec' ),
Field::inst( 'T.PICO' )
->options( Options::inst()
->table('cxprocedure')
->value('procedureID')
->label(array('procedureTag','procedureName'))
->Render( function ( $row ) {
return $row['procedureTag'].' - '.$row['procedureName'];
} )
->where( function ($q) {
$q->where( 'procedureType', 1, '=' );
$q->or_where( 'procedureType', 0, '=' );
} )
->order('procedureType, procedureTag')
)
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which PICO will verify the equipment is installed correctly? Choose "NO TEST" if there is no PICO' )
) ),
Field::inst( 'C1.procedureTag' ),
Field::inst( 'T.SAT' )
->options( Options::inst()
->table('cxprocedure')
->value('procedureID')
->label(array('procedureTag','procedureName'))
->Render( function ( $row ) {
return $row['procedureTag'].' - '.$row['procedureName'];
} )
->where( function ($q) {
$q->where( 'procedureType', 2, '=' );
$q->or_where( 'procedureType', 0, '=' );
} )
->order('procedureType, procedureTag')
//->order('procedureTag')
)
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which SAT will verify the equipment in installed correctly? Choose "NO TEST" if there is no SAT' )
) ),
Field::inst( 'C2.procedureTag' ),
Field::inst( 'T.entity' )
->options( Options::inst()
->table('entity')
->value('entityID')
->label('entityTLA')
->where( function ($q) {
$q->where( 'entityID', 0, '!=' );
} )
->order('entityID')
)
->validator( Validate::dbValues() )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which entity will own the asset when in operation?' )
) ),
Field::inst( 'E.entityTLA' ),
Field::inst( 'A.active' ),
Field::inst( 'D.discipline' ),
Field::inst( 'G.aGroup' ),
Field::inst( 'T.status' )
->options( Options::inst()
->table('active')
->value('activeID')
->label('active')
)
->validator( Validate::dbValues() )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Is this asset type active now?' )
) ),
Field::inst( 'T.count' )
->options( Options::inst()
->table('acount')
->value('countID')
->label('count')
)
->validator( Validate::dbValues() )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'How should these assets be counted?' )
) ),
Field::inst( 'T.zCount' ),
Field::inst( 'C.count' ),
Field::inst( 'T.updatedBy' )
->set('true')
->setValue( $userID ),
/* Field::inst( 'T.lastUpdated' )
->set(true)
->setValue( date("Y-m-d H:i:s") ), /
Field::inst( 'assetCount' )
->dbField('(SELECT DISTINCT COUNT() FROM asset A1 WHERE A1.assetType = T.assetTypeID)')
->set(false),
)
->leftJoin( 'entity E', 'E.entityID', '=', 'T.entity' )
->leftJoin( 'system S', 'S.systemID', '=', 'T.subsystem' )
->leftJoin( 'cxprocedure C1', 'C1.procedureID', '=', 'T.PICO' )
->leftJoin( 'cxprocedure C2', 'C2.procedureID', '=', 'T.SAT' )
->leftJoin( 'active A', 'A.activeID', '=', 'T.status' )
->leftJoin( 'acount C', 'C.countID', '=', 'T.count' )
->leftJoin( 'discipline D', 'D.disciplineID', '=', 'S.discipline' )
->leftJoin( 'agroup G', 'G.aGroupID', '=', 'D.FS' )
//->leftJoin( 'asset A1', 'A1.assetType', '=', 'T.assetTypeID' )
->where('T.status', $del, '=')
->debug(true)
->process( $_POST )
->json();
unset($_SESSION['del']);
<?php > ``` ?>Is it this one which is causing the problem? Do you have an
assetCount
field in your client-side Javascript for Editor?Allan
No that was the field that I am using to run the query for the table, there is no input to the database for that. It was added based on your response to this thread.
Is there a way to tell the editor that there is no database entry for that field?
I thought that was what the ->set(false) was doing, but I gather not.
Yes it is. But it is the only field in the above code that appears to be using an SQL function? Or am I just missing it? Sorry if so!
Perhaps you can show me the JSON returned from the server when you submit an edit please? Since you have debug enabled, that should let me see the SQL being generated.
Allan
Thanks for the response Allan, JSON below: (I removed the data part to stop it being very long).
Just found this goes through the response side:
I've got to confess, I honestly don't know what is causing this here. Those queries are all simple SELECTs and don't appear to be using functions at all, never mind trying to set the value of one.
If you run those queries directly against the database (mySqlAdmin or whatever), what does it give?
Allan
All three SQL statements give their respective ID's.
It's definitely that statement Allan, when I comment it and it's corresponding data tag, the form works.
and another point, this only seems to affect create, edit works fine.
What's odd is that the debug trace SQL statements are only SELECTs not INSERTs (or even UPDATEs).
Are you able to give me a link to the page showing the issue? Between that and the code you've provided above I might be able to figure out what is going wrong here!
Regards,
Allan
Yes, I'll create a public page with the SQL enabled (I've disabled it on the useable site for functionality) and post.
Hi @allan,
You can find a version that you can play with here:
https://assettrack.cx/submissions/submissions1.php
All on a dummy table, so play away as much as you like. Appreciate your help as always.
The server side for his page is below and this page has the same SQL statement as the other which is set to false. (line 89).
```
<?php
//SESSION START
if(!isset($_SESSION)) {
session_start();
if(isset($_SESSION['userID'])) {
$userID = $_SESSION['userID'];
} else {
$userID = null;
}
}
include("../lib/DataTables.php");
use
DataTables\Editor,
DataTables\Editor\Field,
DataTables\Editor\Format,
DataTables\Editor\Join,
DataTables\Editor\Mjoin,
DataTables\Editor\Options,
DataTables\Editor\Upload,
DataTables\Editor\Validate,
DataTables\Editor\ValidateOptions;
Editor::inst( $db, 'submissions1 S', 'S.submissionID' )
->field(
Field::inst( 'S.proTag' )
->options( Options::inst()
->table('cxprocedure')
->value('id')
->label(array('procedureTag','procedureName'))
->Render( function ( $row ) {
return $row['procedureTag'].' - '.$row['procedureName'];
} )
->where( function ($q) {
$q->where( 'docStatus', 3, '!=' );
} )
)
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which procedure was submitted?' )
) ),
Field::inst( 'C.procedureTag' ),
Field::inst( 'C.procedureName' ),
Field::inst( 'S.PDMCNo' )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'What was the PDMC number?' )
) ),
Field::inst( 'S.rev' )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which revision?' )
) ),
Field::inst( 'U1.username' ),
Field::inst( 'S.TxNo' ),
Field::inst( 'S.dateSubmitted' ),
Field::inst( 'S.updated' ),
Field::inst( 'U2.username' ),
Field::inst( 'S.submittedTo' )
->options( Options::inst()
->table('entity')
->value('entityID')
->label('entityTLA')
->where( function ($q) {
$q->where( 'entityID', 0, '!=' );
} )
->order('entityID')
)
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Which Entity is receiving the submission?' )
) ),
Field::inst( 'E.entityTLA' ),
Field::inst( 'S.crr' ),
Field::inst( 'S.receivedStatus' )
->options( Options::inst()
->table('docstatus')
->value('docStatusID')
->label('docStatus')
->where( function ($q) {
$q->where( 'docStatusID', 4, '>=' );
$q->and_where( 'docStatusID', 8, '<' );
$q->or_where( 'docStatusID', 11, '=' );
} )
->order('docOrder')
)
->setFormatter( Format::ifEmpty( null )),
Field::inst( 'D.docStatus' ),
Field::inst( 'S.receivedBack' )
->setFormatter( Format::ifEmpty( null )),
Field::inst( 'daysReview' )
->dbField('IF(S.receivedStatus = 11, "-", IF(S.receivedBack IS NULL, DATEDIFF(NOW(),S.dateSubmitted), DATEDIFF(S.receivedBack,S.dateSubmitted)))')
->set(false),
)
<?php > ``` ?>->leftJoin( 'entity E', 'E.entityID', '=', 'S.submittedTo' )
->leftJoin( 'cxprocedure C', 'C.id', '=', 'S.proTag' )
->leftJoin( 'users_enc U1', 'U1.userID', '=', 'S.submittedBy' )
->leftJoin( 'users_enc U2', 'U2.userID', '=', 'S.updatedBy' )
->leftJoin( 'docstatus D', 'D.docStatusID', '=', 'S.receivedStatus' )
->debug(true)
->process( $_POST )
->json();
Thank you! Although I fear I'm still not seeing what is causing the error.
In
Field.php
can you find this line:And replace it with:
Then let me know and that might hopefully help me track it down.
Regards,
Allan
Done, the error now is this:
Cannot set the value for an SQL function field. These fields are read only:
daysReview === IF(S.receivedStatus = 11, "-", IF(S.receivedBack IS NULL, DATEDIFF(NOW(),S.dateSubmitted), DATEDIFF(S.receivedBack,S.dateSubmitted)))
Thank you! I believe I know what the issue is and it is something I introduced fairly recently unfortunately.
In your local copy of Editor.php find:
and replace it with:
That should resolve the error.
The fix has been committed here.
Allan
Thanks for the help Allan, all working now.