I am trying to set the value of a tinyint field to 1, 2, or 3, but it's not being set. I am pretty new at mySQL, so I am probably making a mistake somewhere, but I can't see it.
I called the function and all the other fields are being set, just not tinyint, which keeps showing as 0.
$this->db->update('jobattachment', ['redline' => $tid], ['id' => $attachmentid], ['editing' => '2']);
I have tried removing the quotes around the 2 and also setting a variable and doing ['editing'] => $editingLevel, but nothing works.
Code for update:
public function update($table = '', $set = NULL, $where = NULL, $limit = NULL)
{
// Combine any cached components with the current statements
$this->_merge_cache();
if ($set !== NULL)
{
$this->set($set);
}
if ($this->_validate_update($table) === FALSE)
{
return FALSE;
}
if ($where !== NULL)
{
$this->where($where);
}
if ( ! empty($limit))
{
$this->limit($limit);
}
$sql = $this->_update($this->qb_from[0], $this->qb_set);
$this->_reset_write();
return $this->query($sql);
}
This is the limit code:
public function limit($value, $offset = 0)
{
is_null($value) OR $this->qb_limit = (int) $value;
empty($offset) OR $this->qb_offset = (int) $offset;
return $this;
}
Your update() function takes 4 parameters, the last of which is an optional limit. When you call it, you are passing 4 parameters, but the last one is an array (['editing' => '2']). My guess is $limit is supposed to be an integer, so your code might generate something like ... LIMIT 5.
So it looks like there is something wrong with how you are passing parameters.
Right now, here's how the variables are set up by the parameters passed to update():
$table = jobattachment
$set = ['redline' => $tid]
$where = ['id' => $attachmentid]
$limit = ['editing' => '2']
My guess is that all the last 3 are supposed to be in $set - you are passing in 3 column names, each with a new value to save.
Again, we can't see your actual set() code, but probably it expects an array of key/value pairs. So you would call update() like this (re-formatted to make it clear that you are passing just 2 parameters, vs 4 previously)
$this->db->update('jobattachment', [
['redline' => $tid],
['id' => $attachmentid],
['editing' => '2']
]);
Now $set is a multi-dimensional array of data to save.
Related
i'm trying to make a subquery something like
SELECT COUNT (*) as total_count FROM ($sql) as count_table
here the method:
public function getTotal($query = null)
{
if (is_null($query)) {
return $this->total;
}
$sql = $query->toSql();
$bindings = $query->getBindings();
foreach ($bindings as $binding) {
$bind = gettype($binding) === '' ? "'" . $binding . "'" : $binding; //is not working as expected
$sql = preg_replace('/\?/', $bind, $sql, 1);
}
dd($sql);
$sql = str_replace('\\', '\\\\', $sql);
$total = \DB::connection('sqlsrv')->select(\DB::raw("select count(*) as total_count from ($sql) as count_table"));
return $total[0]->total_count;
}
the problem is when i preg_replace all ? in the sql query i get only the values without the datatype.
my getBindings():
array:14 [▼
0 => 0
1 => "D"
2 => 0
3 => 0
4 => "CZ"
5 => "00000"
6 => "15000"
7 => "D"
8 => 0
9 => 0
10 => 0
11 => "AT"
12 => "0000"
13 => "2000"
]
in this array i have some integers and strings and i would like to bind exact the same datatypes.
i have tried to check the strings with gettype() but this is not working.
In Laravel 5.6.12, the fromSub() function was added to the query builder that does what you're trying to do.
Untested, but I think your function would look something like:
public function getTotal($query = null)
{
if (is_null($query)) {
return $this->total;
}
return \DB::connection('sqlsrv')
->selectRaw('count(*) as total_count')
->fromSub($query)
->value('total_count');
}
If you're not on 5.6.12 yet, your specific query could be handled wholly using the selectRaw statement, which takes bindings as the second parameter. In this case, your function would look something like:
public function getTotal($query = null)
{
if (is_null($query)) {
return $this->total;
}
return \DB::connection('sqlsrv')
->selectRaw('count(*) as total_count from ('.$query->toSql().') as count_table', $query->getBindings())
->value('total_count');
}
Note: if you haven't seen it before, the value() function executes the query, takes the first row, and then gets the value of the specified column from that first row. Just a little cleaner than using get() or first() and then accessing the property.
I am using Codeigniter 3, PHP and MySQL.
I'm trying to select a record from a MySQL database, and depending on the result run an update query.
If result = 0, update.
If result = 1, do nothing.
My code so far is;
public function addData($itemId) {
$gDescription = 'test';
$gPreviewLink = 'test';
$gThumbnail = 'test';
$gPageCount = 'test';
$this->db->select('g_data');
$this->db->from('item');
$this->db->where('item_id', $itemId);
$query = $this->db->get();
$result = $query->result();
// var_dump($result) returns array(1) { [0]=> object(stdClass)#22 (1) { ["g_data"]=> string(1) "0" } }
$data = array(
'item_description' => $gDescription,
'item_preview_link' => $gPreviewLink,
'item_thumbnail' => $gThumbnail,
'item_pageCount' => $gPageCount,
'g_data' => '1',
'g_data_timestamp' => 'NOW()'
);
// if result = 0 update
if($result == '0') {
$this->db->where('item_id',$itemId);
$this->db->update('item', $data);
}
}
Is there any reason the data won't update in my database? I'm not receiving any error messages.
Any help would be appreciated.
$query->result() returns an array of objects where each object is a row from the table. (As you can see in the var_dump in your comments)
Without other changes your conditional should be
if($result->g_data == '0') { ...
That said, you should have checked earlier in the method that the database atually returned results. Also, you don't need more than one row so don't use result() use 'row()' instead
...
$query = $this->db->get();
// The following will set $result to the value of "g_data" if there
// are rows and to "0" if there are none.
$result = $query->num_rows() > 0 ? $query->row()->g_data: '0';
...
If you do the above then the conditional can remain as you have it coded
if($result == '0') {...
Executing the SELECT query means making an unnecessary extra trip to the database. Just build your 0 criteria into your UPDATE query -- if it is not satisfied, then no rows will be affected.
Code:
$data = [
'item_description' => $gDescription,
'item_preview_link' => $gPreviewLink,
'item_thumbnail' => $gThumbnail,
'item_pageCount' => $gPageCount,
'g_data' => '1'
];
$this->db->where([
'item_id' => $itemId,
'g_data' => 0
]);
$this->db->set('g_data_timestamp', 'NOW()', false);
$this->db->update('item', $data);
// return (bool)$this->db->affected_rows();
All done in a single query execution. I also took the liberty of demonstrating how to pass a MySQL function as a value using set()'s third parameter.
This is the first time i create my own webservice (someone always did it for me before), so please bear with me.
I post this array :
$data = array(
'user_id' => $this->post('user_id'),
'group_id' => $this->post('group_id'),
'child_id' => $this->post('child_id'), //will be nested array
'custom' => $this->post('custom'),
'time' => $this->post('time'),
'date' => $this->post('date')
);
I tried to create a nested array with this : $this->post('child_id'), because user can post multiple child_id at once.
Then i tried to iterate through the child_id, because i need to insert them to the mysql :
for($i = 0; $i < sizeof($data['child_id']); $i++)
{
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data, $result_id[0]['id']);
}
What should i do, so i can have an array of child_id in my $data array? (nested array)
And how to iterate through it?
UPDATE :
I have updated the codes above.
I use advanced rest client for testing, and i tried to post something like this in the form content type :
child_id=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id=2
Notice that theres two child_id (left most and right most), but only the last one (right most) is inserted.
And this is the add_trans in the model :
function add_trans($table, $data, $schedule_id) {
$query = $this->db->insert($table, array('child_id' => $data['child_id'], 'schedule_id' => $schedule_id));
return $query;
}
Thanks a lot for your time.
Even thought you set the name attribute as child[] on the markup,
You still need to call it as:
'child_id' => $this->post('child_id')
It will still return an array.
for($i = 0; $i < sizeof($data['child_id']); $i++) {
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data, $result_id[0]['id']);
}
EDIT:
Looking upon you query string, that seems to be the culprit:
child_id=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id=2
^ same index , same index, same index, it will overwrite and you will get only `2`
If you want to get them all into an array format, you need to set them like this
child_id[]=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id[]=2
^ it needs to be set like this
UPDATE:
And in your model, if you want each id per row, well you can also loop in this case:
function add_trans($table, $data, $schedule_id) {
foreach($data['child_id'] as $child_id) {
$query = $this->db->insert($table, array('child_id' => $child_id, 'schedule_id' => $schedule_id));
}
// return $this->db->insert_id();
return $query;
}
ofcourse that won't work, it has to be
for($i = 0; $i < sizeof($data['child_id']); $i++)
{
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data['child_id'][$i], $result_id[0]['id']);
}
because you've not set $data['child_id[]'] so it doesn't exist, the key is just a string or number, it does not validate or parse anything
you don't need to give child[] in post method. just give only child, it will get complete array what are you sending from views
replace
'child_id' => $this->post('child_id[]')
with
'child_id' => $this->post('child_id')
I needed a function that recursively parses a multi-dimensional array for a (part) of a certain string value and, if found, returns the entire value the string is contained in.
I came up with the following solution:
function & ransackArray(array & $haystack, $needle) {
foreach($haystack as &$element) {
if(is_array($element)){
if($v=ransackArray($element, $needle))
return $v;
} else {
if(strstr($element, $needle))
return $element;
}
}
return false;
}
This works fine. For instance, providing:
$data=array(
'key' => 'something',
'children' => array(
'someValue' => 'myTest',
'someMore' => 'yes'
)
);
And running:
$r=ransackArray($data, 'myTes');
This will result in $r containing 'myTest'.
The problem is that now that i found this value, i want to change it in $data, right on the fly, by writing:
$r='new value';
Which should then effectively result in data looking like this:
$data=array(
'key' => 'something',
'children' => array(
'someValue' => 'new value',
'someMore' => 'yes'
)
);
This however, doesn't seem to work. Perhaps i misunderstand something about references. In any case, the reason i needed this to work is why i pass $haystack as a reference and also return the function's result as one.
Can this be done? If yes, how? And if not - why not?
You're missing two ampersands...one on this line:
if($v = self::ransackArray($element, $needle))
which should be:
if($v = &self::ransackArray($element, $needle))
and one on this line:
$r = ransackArray($data, 'myTes');
which should be:
$r = &ransackArray($data, 'myTes');
(Note: it looks like your ransackArray function is actually a method in a class, so if you're calling that method from within the class it would be $r = &$this->ransackArray($data, 'myTes');)
When passing variables to a function, you don't need to use & - just put the & in front of the parameter in the function signature - but in cases like yours where you are getting a return value from a function, there needs to be a & both in the function call and in the function signature. For more info see http://www.php.net/manual/en/language.references.pass.php
I have reached very strange problem using Zend Framework 1 and binding the resultset to BvbGrid.
We have a method which queries an external API. You need to specify the following params: methodName, params.
So the controller recieves a resultset as an array from the external API.
The resultset (in the database) is 4 columns - 1 string, 2 DateTime, 3 int, 4 int. And is with about 3000 rows.
When I recieve the resultset in the controller I bind it to Bvb Grid, which should evaluate in the view as columns with search boxes.
So far, so good, when I search in the first or in the last column (string, int), it searches in the whole resultset.
But when I search 2, 3 (DateTime, int) it searches only in the current page.
I don't understand why is that. There is no difference in data binding, or something.
The code is as follows
public function indexAction() {
$pagesize = $this->_request->getPost('rows');
$pagenum = $this->_request->getPost('page');
$pagesize = ($pagesize) ? $pagesize : 30;
$pagenum = ($pagenum) ? $pagenum : 1;
$params = array();
$params['page_num'] = $pagenum;
$params['page_limit'] = $pagesize;
if ($this->_request->isXmlHttpRequest()) {
// additional search filter
if ($this->_request->getPost('username')) {
$params['username'] = $this->_request->getPost('username');
}
if ($this->_request->getPost('lastlogin')) {
$params['lastlogin'] = $this->_request->getPost('lastlogin');
}
if ($this->_request->getPost('type')) {
$params['type'] = $this->_request->getPost('type');
}
if ($this->_request->getPost('level')) {
$params['level'] = $this->_request->getPost('level');
}
}
if (($order_by = $this->_request->getPost('sidx')) && ($order_type = $this->_request->getPost('sord'))) {
$params['order_by'] = $order_by;
$params['order_by_type'] = $order_type;
}
$resultset = $this->web_service->_apiRequest('SearchUsers', $params);
/**
* The resultset is like
* array(
'found_rows' => 3000,
'body' => array(
'username' => 'blabla',
'lastlogin' => '2014-02-25 13:33:38.1234',
'type' => 1,
'level' => 199
)
);
*/
$this->view->count = $resultset['found_rows'];
if ($resultset['found_rows'] > 0 || $this->_request->isXmlHttpRequest()) {
$grid = new Bvb_Grid_Deploy_JqGrid($this->_gridconfig);
$grid->setSource(new Bvb_Grid_Source_Array($resultset['body']));
$grid->getSource()->setTotalRecords($resultset['found_rows']);
$grid->updateColumn('username', array('width' => '110',));
$grid->updateColumn('lastlogin', array('width' => '110',));
$grid->updateColumn('type', array('width' => '110',));
$grid->updateColumn('level', array('width' => '110',));
$grid->setJqgParams(array('caption' => 'resultset'
, 'forceFit' => true
, 'viewrecords' => true
, 'rowList' => array(15, 30, 50)
, 'altRows' => false
)
);
$grid->ajax(get_class($grid));
$grid->setNumberRecordsPerPage(30);
$grid->setExport(array());
$this->view->grid = $grid->deploy();
}
I have tried to examine the BvbGrid's code, but found nothing strange.
In another project the same code is used, and it works fine, without any problems on searching in any column. I have dump'd the API response to be sure it gives me 3000 records, and it actually is and they are in the way as in the comment. I really cannot find the reason why i.e. the lastlogin column searches only on the current page.
If someone can help me, or give me directions where to look at to fix the issue (maybe somewhere in the BvbGrid's code?) I will appreciate it.
Thank you in advance.