I want to make a query that results like this in codeigniter MODEL:
$caldata = array (
15 => 'yes',
17 => 'no'
);
Is that possible to do?
Take NOTE: The 15,17 and yes,no are in the same database table.
There is no core helper function to achieve what you want in CI. But you can create your own helper function:
function pluck($arr = [], $val = '', $key = '')
{
// val - label for value in array
// key - label for key in array
$result = [];
foreach ($arr as $value) {
if(!empty($key)){
$result[$value[$key]] = $value[$val];
}else{
$result[] = $value[$val];
}
}
return $result;
}
you can use result_array() function so you can have something like:
$query = $this->db->select('id,answer')->from('users')->get();
$result = $query->result_array();
print_r($result);
After that you have your array and you can make the $key => $value relation of the fields
After a long search i found an answer. Sample way to do this:
$query = $this->db->select('start_date, class')->from('event')->like('start_date', "$year-$month", 'after')->get();
$datavariable = $query->result();
$caldata = array();
foreach($datavariable as $row){
$caldata[substr($row->start_date,8,2)] = $row->class;
}
I have a CodeIgniter/PHP Model and I want to insert some data into the database.
However, I have this set in my 'raw' SQL query:
ON DUPLICATE KEY UPDATE duplicate=duplicate+1
I am using CodeIgniter and am converting all my previous in-controller SQL queries to ActiveRecord. Is there any way to do this from within the ActiveRecord-based model?
Thanks!
Jack
You can add the "ON DUPLICATE" statement without modifying any core files.
$sql = $this->db->insert_string('table', $data) . ' ON DUPLICATE KEY UPDATE duplicate=LAST_INSERT_ID(duplicate)';
$this->db->query($sql);
$id = $this->db->insert_id();
I hope it's gonna help someone.
The below process work for me in Codeigniter 3.0.6
public function updateOnDuplicate($table, $data ) {
if (empty($table) || empty($data)) return false;
$duplicate_data = array();
foreach($data AS $key => $value) {
$duplicate_data[] = sprintf("%s='%s'", $key, $value);
}
$sql = sprintf("%s ON DUPLICATE KEY UPDATE %s", $this->db->insert_string($table, $data), implode(',', $duplicate_data));
$this->db->query($sql);
return $this->db->insert_id();
}
Following the snippet linked by Pickett, I made a few modifications to:
1) Update it to use the new Query Builder (CI 3), formerly known as Active Record.
2) You can now pass an associative array (key => value) or an array of associative arrays. In the second form, it performs a multi-update.
I only tested it with mysqli, and it works well.
This piece of code goes in system/database/drivers/mysqli/mysqli_driver.php
function _duplicate_insert($table, $values)
{
$updatestr = array();
$keystr = array();
$valstr = array();
foreach($values as $key => $val)
{
$updatestr[] = $key." = ".$val;
$keystr[] = $key;
$valstr[] = $val;
}
$sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") ";
$sql .= "VALUES (".implode(', ',$valstr).") ";
$sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr);
return $sql;
}
function _multi_duplicate_insert($table, $values)
{
$updatestr = array();
$keystr = array();
$valstr = null;
$entries = array();
$temp = array_keys($values);
$first = $values[$temp[0]];
foreach($first as $key => $val)
{
$updatestr[] = $key." = VALUES(".$key.")";
$keystr[] = $key;
}
foreach($values as $entry)
{
$valstr = array();
foreach($entry as $key => $val)
{
$valstr[] = $val;
}
$entries[] = '('.implode(', ', $valstr).')';
}
$sql = "INSERT INTO ".$table." (".implode(', ',$keystr).") ";
$sql .= "VALUES ".implode(', ',$entries);
$sql .= "ON DUPLICATE KEY UPDATE ".implode(', ',$updatestr);
return $sql;
}
And this goes into the /system/database/DB_query_builder.php file:
function on_duplicate($table = '', $set = NULL )
{
if ( ! is_null($set))
{
$this->set($set);
}
if (count($this->qb_set) == 0)
{
if ($this->db_debug)
{
return $this->display_error('db_must_use_set');
}
return FALSE;
}
if ($table == '')
{
if ( ! isset($this->qb_from[0]))
{
if ($this->db_debug)
{
return $this->display_error('db_must_set_table');
}
return FALSE;
}
$table = $this->qb_from[0];
}
$is_multi = false;
foreach (array_keys($set) as $k => $v) {
if ($k === $v) {
$is_multi = true; //is not assoc
break;
}
}
if($is_multi)
{
$sql = $this->_multi_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set );
}
else
{
$sql = $this->_duplicate_insert($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_set );
}
$this->_reset_write();
return $this->query($sql);
}
Then you can do this for a single row insert/update:
$this->db->on_duplicate('table', array('column1' => 'value', 'column2' => 'value'));
Or this for a multi insert/update:
$this->db->on_duplicate('table', array(
array('column1' => 'value', 'column2' => 'value'),
array('column1' => 'value', 'column2' => 'value')
));
You can tweak the active record function with minimal addition:
DB_driver.php add inside the class:
protected $OnlyReturnQuery = false;
public function onlyReturnQuery($return = true)
{
$this->OnlyReturnQuery = $return;
}
find function query( ...and add at the very beginning:
if ($this->OnlyReturnQuery) {
$this->OnlyReturnQuery = false;
return $sql;
}
and finally in DB_active_rec.php add function:
public function insert_or_update($table='', $data=array())
{
$this->onlyReturnQuery();
$this->set($data);
$insert = $this->insert($table);
$this->onlyReturnQuery();
$this->set($data);
$update = $this->update($table);
$update = preg_replace('/UPDATE.*?SET/',' ON DUPLICATE KEY UPDATE',$update);
return $this->query($insert.$update);
}
Now you can use it as:
$this->db->insert_or_update('table',array $data);
Pros:
uses all the active record validation
Cons:
it is not the best (the most proper) way of extending the function, because if you are planning to update these files, you will have to redo the procedure.
The link to the forum thread above is broken. I don't know of a better way than just using db->query for the call, if someone has a better solution, please post that.
$result = $this->CI->db->query(
"INSERT INTO tablename (id, name, duplicate) VALUES (1, 'Joe', 1) ".
"ON DUPLICATE KEY UPDATE duplicate=duplicate+1");
I hope this helps someone looking for a solution to this.
Below is a code snippet I use everytime for update on duplicates:
$sql = "insert into table_name (id, name) values(".$id.",'".$name."') on duplicate key update id=".$id.",name='".$name."'";
//Executing queries
$result = $this->db->query($sql, array($id, $name));
Note: column id must be primary or unique
Using $this->db->query() and parameters, this is how I do it. the first 4 parameters are for the insert part and the last three parameters are repeated for the on duplicate key update part.
$sql = "insert into application_committee ".
"(application_id, member1_id, member2_id, member3_id) values (?, ?, ?, ?)".
" on duplicate key update member1_id = ?, member2_id = ?, member3_id = ?";
$this->db->query($sql, array($appid, $member_1, $member_2, $member_3,
$member_1, $member_2, $member_3);
Simply done -
$updt_str = '';
foreach ($insert_array as $k => $v) {
$updt_str = $updt_str.' '.$k.' = '.$v.',';
}
$updt_str = substr_replace($updt_str,";", -1);
$this->db->query($this->db->insert_string('table_name', $insert_array).' ON DUPLICATE KEY UPDATE '.$updt_str);
I used mongo odm query for getting data according to id i want to get query data and return this data in json format,how i do this?
here is my code:
public function loadAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
$dm = $this->getServiceLocator()->get('doctrine.documentmanager.odm_default');
$data = $this->dm->createQueryBuilder('Calendar\Document\Event')
->field('calendar_id')->equals($id)->getQuery()->execute();
//$count_tags = $eventdata->count();
$array = array();
if($data && !is_null($data) && is_object($data)){
foreach($data as $key=>$value) {
$array[] = $value;
}
}
return $this->getResponse()->setContent(Json::encode($array));
}
You can accomplished this by following
return new JsonModel($arrayVaraible);
you might need to import
Zend\View\Model\JsonModel;
Hope That helps
fetchresultsAction
public function fetchresultsAction() {
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
//$form_data = $this->getRequest()->getPost();
//$examcatID = $form_data['examcatID'];
$examID = 'Exam_ID_001';
$Exam_Results = new Admin_Model_Examresults();
$results = $Exam_Results->fetchExamResults($examID);
foreach ($results as $value) {
print_r($value['subjectID']);
echo '<br/>';
}
}
Model > Examresults
public function fetchExamResults($examID) {
$sel = $this->select();
$sel->distinct();
$sel->where('examID=?', $examID);
$result = $this->fetchAll($sel); // fetch the rows to the array called result
return $result;
}
This Code is not work.I need have to get NON-Duplicate values of subjectID from mysql database.How Can I do that.Please help me to solve this problem.
Note : This is Zend 1.12 version
Try using print_r($value->subjectID)
I have two database tables, one for allowances and one for deductions. I want to calculate net salaries.
I'm using CodeIgniter. Here's my current code:
function get_allowances($eid)
{
$this->db->from('allowances');
$this->db->where('eid',$eid);
$query = $this->db->get();
if($query->num_rows()==1)
{
return $query->row();
}
else
{
//Get empty base parent object, as $item_id is NOT an item
$salary_obj=new stdClass();
//Get all the fields from items table
$fields = $this->db->list_fields('allowances');
foreach ($fields as $field)
{
$salary_obj->$field='';
}
return $salary_obj;
}
}
function get_deductions($eid)
{
$this->db->from('deductions');
$this->db->where('eid',$eid);
$query = $this->db->get();
if($query->num_rows()==1)
{
return $query->row();
}
else
{
//Get empty base parent object, as $item_id is NOT an item
$salary_obj=new stdClass();
//Get all the fields from items table
$fields = $this->db->list_fields('deductions');
foreach ($fields as $field)
{
$salary_obj->$field='';
}
return $salary_obj;
}
}
and in controller,
function net_salary($eid)
{
$allownces[] = $this->Salary->get_allowances($eid);
$deductions[] = $this->Salary->get_deductions($eid);
return $net_salary = array_sum($allownces) - array_sum($deductions);
}
My net_salary() function gives me a result of 0. What am I doing wrong, and how can I fix it?
Your models with plural names are only going to return a single object.
so what you are ending up with is...
Array
(
[0] => allowance_object
)
and
Array
(
[0] => deduction_object
)
While we really need the schema of your database try this (and make same edits for deductions)...
function get_allowances($eid)
{
$this->db->from('allowances');
$this->db->where('eid',$eid);
$query = $this->db->get();
if($query->num_rows()==1)
{
return $query->row_array(); //<--- return an Array
}
else
{
// make an array instead of object
$salary_obj = array();
//Get all the fields from items table
$fields = $this->db->list_fields('allowances');
foreach ($fields as $field)
{
$salary_array[$field] = 0; //<---- add array keys and set to integer 0 instead of empty string.
}
return $salary_array;
}
}
then in your net_salary function
function net_salary($eid)
{
$allownce = $this->Salary->get_allowances($eid);
$deduction = $this->Salary->get_deductions($eid);
return array_sum($allownce) - array_sum($deduction);
}
Try something like this:
function get_values($eid, $table_name)
{
$this->db->where('eid',$eid);
$query = $this->db->get($table_name);
$salary_obj = $query->result();
$values = array();
foreach($salary_obj as $row){
$values[] = $row->value_column_name;
}
return $values;
}
where value_column_name is the name of the table column (filedname) where the desired value stands.
call in controller:
function net_salary($eid)
{
$allownces = $this->Salary->get_values($eid, 'allowances');
$deductions = $this->Salary->get_values($eid, 'deductions');
return $net_salary = array_sum($allownces) - array_sum($deductions);
}