I am having an issue with updating a MySql table using codeigniter.
Basically, its inserting 'img' the characters, into the table rather than the value of the variable.
This is so strange!
Here is my model:
public function update_course_progress($progress_data) {
$course_id = $progress_data['course_id'];
$user_id = $progress_data['user_id'];
$progress = $progress_data['progress'];
$status = $progress_data['status'];
$update_data = array (
'progress' => $progress,
'status' => $status,
);
// perform update on the matching row
$this->db->update('training_stats', $update_data, array('course_id' => $course_id, 'user_id' => $user_id));
}
So, the issue is with 'progress' instead of inserting the value of this variable it is inserting 'img'???
So, if i var_dump $update_data i get this:
array(2) {
["progress"]=> string(2) "1a"
["status"]=> string(1) "i"
}
Which is correct:
And if i use the profiler in CI to get the db queries, this is what I get:
UPDATE `training_stats`
SET `progress` = '1a', `status` = 'i'
WHERE `course_id` = '8'
AND `user_id` = '2'
Which is correct.
So WHY ON EARTH is it inserting null into the db instead of 1a.
The table structure for this column is VARCHAR(4).
progress varchar(4) NOT NULL DEFAULT '0',
What the hell is going on? why on earth is it img input???
What can be wrong?
UPDATE:
As i was debugging, i tried an insert instead of an update, and 2 rows were inserted. The first row was the expected data, and the second row was the data with 'img' in it. Both rows were the same except for the 'progress' column, which had img inserted in the second row.
So obviously it had been updating the row with the correct data and then overwriting it with the incorrect data.
But now why are there 2 rows being inserted? There is no loop? and why is the CI profiler not logging the second query, if that is indeed what is happening
As of per documentation of CI I will use the more standard method of updating data.
$updateArray = array (
'progress' => $progress_data['progress'],
'status' => $progress_data['status'],
);
$whereArray = array(
'course_id' => $progress_data['course_id'],
'user_id' => $progress_data['user_id']
)
$this->db->set($updateArray);
$this->db->where($whereArray);
$this->db->update('training_stats');
This should do, I also think you shouldn't put extra variables for the data as you did. With such short function you really are not having any benefits sinds all data is only accessed once and seem like unnecessary to me, though opinions could vary.
Related
I'm trying to insert an array of data into a table in database but an error said Array to string conversion error
This is the post function in my controller, first i post an array of data. The values of the array will be the names, and numbers, they are not id. The id is only kodejdwl. This will be pass to my model
function index_post() {
$data = array(
'kodejdwl' => $this->post('kodejdwl'),
'tahun_akad' => $this->post('kode_tahun_akad'),
'semester' => $this->post('semester'),
'mk' => $this->post('mk'),
'ruangan' => $this->post('ruangan'),
'nama_dosen' => $this->post('nama_dosen'),
'namakelas' => $this->post('nama_kelas'),
'jam_mulai' => $this->post('jam_mulai'),
'jam_selesai' => $this->post('jam_selesai'),
);
}
After the data from above code is passed to the model. I created some new variables which are the id of each the name of the value in the array data. e.g if the value of data['mk'] is Website then the id will be 1 and that id will be stored in variable $kodemk and i do it to each value in the data. Then i created new_data which stores array of the id's which i previously made. Then i insert that array into one table in my database. I thought it would be fine but it said Array to string conversion error. What should i do so i could insert that array into the table in my database?
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->result();
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->result();
$this->db->flush_cache();
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->result();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->result();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->result();
$this->db->flush_cache();
$this->db->select('kode_jam');
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->result();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id,
'matakuliah_kodemk' => $kode_mk,
'ruangan_namaruang' => $ruangan,
'staff_nip' => $nip_dosen,
'kelas_kodeklas' => $kodeklas,
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
You probably want to use row() instead of result() because it'll contain only one result that you want. If you want to use result() and store multiple values then you'll have to use implode to concatenate them and store it as a string.
I've written a possible solution for your problem; Some things were missing, so I've mentioned them in the comments. See if this helps you.
public function insert($data){
$this->db->select('thn_akad_id');
$tahunakad_id = $this->db->get_where('tik.thn_akad',array('tahun_akad'=>$data['tahun_akad'],'semester_semester_nm'=>$data['semester']))->row(); // use row here
$this->db->flush_cache();
$this->db->select('kodemk');
$kode_mk = $this->db->get_where('tik.matakuliah',array('namamk'=>$data['mk']))->row();
$this->db->flush_cache();
// remove your_ruangan_column with your desired column name
$this->db->select('your_ruangan_column');
$ruangan = $this->db->get_where('tik.ruangan', array('namaruang' => $data['ruangan']), 1)->row();
$this->db->flush_cache();
$this->db->select('nip');
$nip_dosen = $this->db->get_where('tik.staff',array('nama'=>$data['nama_dosen']))->row();
$this->db->flush_cache();
$this->db->select('kodeklas');
$kodeklas = $this->db->get_where('tik.kelas',array('namaklas'=>$data['namakelas']))->row();
$this->db->flush_cache();
// Not sure where this ↓↓ is being used but you can use it the same way as others
$this->db->select('kode_jam');
// duplicate variable name here ↓↓ (fix this)
$kode_mk = $this->db->get_where('tik.wkt_kuliah',array('jam_mulai'=>$data['jam_mulai'],'jam_selesai'=>$data['jam_selesai']))->row();
$this->db->flush_cache();
$new_data = array(
'kodejdwl' => $data['kodejdwl'],
'thn_akad_thn_akad_id' => $tahunakad_id->thn_akad_id, // {$tahunakad_id} consists an object with the key {thn_akad_id}-- table_column_name
'matakuliah_kodemk' => $kode_mk->kodemk, // ...
'ruangan_namaruang' => $ruangan->your_ruangan_column, // ...
'staff_nip' => $nip_dosen->nip, // ...
'kelas_kodeklas' => $kodeklas->kodeklas // ...
);
$insert = $this->db->insert('tik.jadwal_kul', $new_data);
return $this->db->affected_rows();
}
Your are making a total of 7 separate trips to the database. Best practice recommends that you always minimize your trips to the database for best performance. The truth is that your task can be performed in a single trip to the database so long as you set up the correct INSERT query with SELECT subqueries.
I don't know what your non-English words are, so I will use generalized terms in my demo (I've tested this successfully in my own CI project). I am also going to reduce the total subqueries to 3 to reduce the redundance in my snippet.
$value1 = $this->db->select('columnA')->where('cond1', $val1)->get_compiled_select('childTableA');
$value2 = $this->db->select('columnB')->where('cond2', $val2)->get_compiled_select('childTableB');
$value3 = $this->db->select('columnC')->where('cond3', $val3)->get_compiled_select('childTableC');
return (int)$this->$db->query(
"INSERT INTO parentTable
(column1, column2, column1)
VALUES (
($value1),
($value2),
($value3)
)"
);
// to mirror your affected rows return... 1 will be returned on successful insert, or 0 on failure
Granted this isn't using the ActiveRecord technique to form the complete INSERT query, but this is because CI doesn't allow subqueries in the VALUES portion (say, if you were to use the set() method). I am guessing this is because different databases use differing syntax to form these kinds of INSERTs -- I don't know.
The bottom line is, so long as you are fetching a single column value from a single row on each of these sub-SELECTs, this single query will run faster and with far less code bloat than running N number of individual queries. Because all of the variables involved are injected into the sql string using get_compiled_select() the stability/security integrity should be the same.
I am using Cakephp 3 and trying to get some rows/records from a table having a field as non empty.
For example:-
I have a areas table with a field named Area_block. I need to fetch records for those rows which have something inside Area_block. In simple words, I don't need empty or NULL Area_block rows.
Area_block is not a NULL field by default. So it remains empty/blank.
I have tried
$conditions = ['Area_Block IS NOT NULL'];
$conditions = ['NOT' => array('Area_Block' => '')];
$conditions = ['Area_Block <>' => ''];
$conditions = ['Area_Block !=' => ''];
but nothing works !!
My environment includes MSSQL server 2008 and PHP 5.6 on apache.
Please help !!
I understand your table holds records with Area_Block set both to NULL and '' (empty string).
Try the following:
$conditions = [['Area_Block IS NOT' => null], ['Area_Block IS NOT' => '']];
This should also work:
$conditions = ['Area_Block IS NOT' => [null,'']]; //haven't tested it
However, in order to reduce complexity, in the database you may want to set the Area_Block field either to default to NULL, or default to '' and prevent the field from accepting NULL values.
Working exclusively with NOT NULL values might be easier. If you alter the table to reflect this, you would only need to check for '' values:
$conditions = ['Area_Block IS NOT' => ''];
See Automatic IS NOT NULL Creation in the 3.x Cookbook.
I think the solution provided by #InigoFlores worked to some extend but was failing for some records.
Here's what I did to make it work perfectly.
$conditions = ['DATALENGTH(Area_Block) >' => 0];
I Hope it helps someone.
I'm using PostgreSQL & Codeigniter. There is a table called folio in the database. It has few columns containing remarks1, remarks2, remarks3 as well. Data for the all the other columns are inserted when the INSERT statement executes for the 1st time.
When I try to execute below UPDATE statement later for the below 3 columns, remarks1 column get updated correctly. But remarks2, remarks3 columns are updated with ''.
UPDATE "folio" SET "remarks1" = 'test remark', "remarks2" = '', "remarks3" = '' WHERE "id" = '51';
Given that remarks1, remarks2, remarks3 columns data type is character varying. I'm using Codeigniter active records. At a time all 3 columns could be updated else single column could be updated depending on the user input.
What could be the issue? How can I fix this? Why columns are updated with ''?
As requested the php array in CI would be below
$data = array(
'remark1' => $this->input->post('remark1'),
'remark2' => $this->input->post('remark1'),
'remark3' => $this->input->post('remark1')
);
Function which saves the data contains below two lines only
$this->db->where('id', $folio_id);
$this->db->update('folio', $data);
Those columns are updated with '' because you tell them to?
Let's take a closer look at the query
UPDATE "folio"
SET
"remarks1" = 'test remark',
"remarks2" = '',
"remarks3" = ''
WHERE
"id" = '51';
First you select the table folio for the update.
Then you tell it to update remarks1 through remarks3 with new values. For remarks2 and remarks3 you specify to set them to an empty string. And that's what's going to happen.
Last but not least, you tell it to only apply this update to rows where id equals 51.
So, in order to only update remarks1 you can simply remove the other columns from your update:
UPDATE "folio"
SET
"remarks1" = 'test remark'
WHERE
"id" = '51';
Update:
I'm by far not a CI expert, but from what I see, I'd change the $data array to only contain information for remark1:
$data = array(
'remark1' => $this->input->post('remark1')
);
And (from my understanding) it should only update this single column.
I have a table of values that uses a Where clause to find the row and then updates the values in the row. However it is deleting the value it is searching for after it is already found. So it finds the row using the stockid (not a PK) and updates the row, but leaves the stockid blank afterwards
$data = array(
'towSet' => $towSet,
'transWare' => $transWare,
'oceanFreightBooked' => $oceanFreightBooked,
'BOLrec' => $BOLrec,
'BOLsent' => $BOLsent,
);
$this->db
->where('stockid', $stockHold)
->update('logistics_tracking', $data);
The Strange part is that using this code doing the same thing it works perfectly fine
$data = array(
'recTitle' => $recTitle,
'recPOA' => $recPOA,
'recTitleState' => $recTitleState,
'titleSent' => $titleSent,
);
$this->db
->where('stockid', $stockHold)
->update('title_tracking', $data);
So as a reminder all the other values (towSet, transWare, oceanFreightBooked, ect.. ) all insert and it just blanks out the stockid after updating
Any ideas would be greatly appreciated
Yeah the code was fine, apparently I was just doing too much with one function. Created an external function and passed through an array of the data. Weird.
Thanks for looking!
So this is my conclusion of the real problem from a question I asked earlier here:
SQL Select Query with CodeIgniter's active records and 'where sha1' returns first row entry
I'm also double posting in the CodeIgniter forum:
http://codeigniter.com/forums/viewthread/194502/ (latest progress...)
You can get several code snippets from both.
In short, the problem I am having is the following and I'm not sure who's really the culprit:
I am using an array as shown below to define the 'where' in a select query for an active records function. The query gives me all the rows in the table if used in the certain combination outlined below.
pasting---
it actually looks like this combination of error only happens when sha1 returns raw output data and email < 1 For instance:
$where = array(
'email' => 0,
'password' => sha1(false, true), # sha1($this->input>post('password'), true);
);
if sha1(false, true) is changed to sha1(whatever) there is no error. (‘whatever’ includes strings, booleans, etc.)
if array is unchanged and 'email' => 0 is changed to 'email' => '0' which happens in the SQL QueryA, then it works correctly. If I remove the ‘‘s from the value in QueryA as in Active Records then I get all the rows again …
Also, I do not get any rows (which is correct) when 'email' is > 0. i.e. 'email' => 1 (2,3,etc) and even when 'email' => null.
The combination of ‘email’ = 0 and sha1(‘any value’, true) results in returning EVERY row in the table in the Active Records because there’s no quotes added to the value 0. Quotes are however added around the ‘password’ = ‘value’. If there are no quotes around the raw hash, then SQL returns an Error and prevents the script from running.. (which is better than returning ever row…)
This could be an SQL error since it only happens on a value of 0... but is it user error to not quote a where value? If so, then should Active Records should quote the value for me automatically if it is an integer or not? It seems to do it for string values, but not integers (false = 0, true = 1)...
If you want the same result in your queries, write the two equal. In QUERY1 you define your terms as follows:
WHERE `email` = \''.$data['email'].'\'
AND `password` = \''.$data['password'].'\'
in QUERY2
# data for sql query
$where = array(
'email' => $this->input->post('email'),
'password' => sha1($this->input->post('password'), true);
);
For QUERY1 and QUERY2 are equal, QUERY2 would be:
# data for sql query
$where = array(
'email' => "'".$this->input->post('email')."'",
'password' => sha1($this->input->post('password'), true);
);
Codeigniter can not determine by itself that 0 should not be a number. You do it yourself as QUERY1.