I want to insert the records (that i got from a table) to another table using codeigniter.
here's the function to add the record. I pass the $nokw to insert to another table as foreign key.:
function add_detail($nokw){
$id_sj = $this->session->userdata('id');
$upddate = date('Y')."-".date('m')."-".date('d')." ".date('H').":".date('i').":".date('s');
$i=0;
$this->suratjalan->where('IDDeliveryNo',$id_sj);
$rec = $this->suratjalan->get("t02deliveryno_d")->result_array();
// parse the result and insert it into an array
foreach ($rec as $det){
$i++;
$detail[$i] = array(
'ID' => '',
'NoKwitansi' => $nokw,
'TypeProduct'=> $det['TypeProduct'],
'PartNo' => $det['PartNo'],
'PartNoVendor'=> $det['PartNoVendor'],
'SerialPanel' => $det['SerialPanel'],
'Description' => $det['Description'],
'Dimension' => $det['Dimension'],
'DescriptionVendor' => $det['DescriptionVendor'],
'DimensionVendor' => $det['DimensionVendor'],
'PrintedProduct' => $det['PrintedProduct'],
'Qty' => $det['Qty'],
'UoM' => $det['UoM'],
'Remark' => $det['Remark'],
'UpdUser'=> $this->session->userdata('user'),
'UpdDate'=> $upddate
);
// insert the record
$this->finance->insert('t02fkpd',$detail[$i]);
}
}
It works, but it doesn't work if more than one row is returned from the table 't02deliveryno_d'. I think the error comes when i insert the record. i use the $i++to make different index in $detail array.
How can I fix this to properly insert multiple rows?
You didn't show the db schema, but I'm assuming that t02fkpd.ID is an auto-incrementing column.
If that's the case, the problem is that you're specifying a blank value for ID instead of letting the database handle it. This is probably resulting in attempts to insert duplicate rows with the same (blank) id.
Here's an updated version of your function that I suspect will work better:
function add_detail($nokw) {
$id_sj = $this->session->userdata('id');
$upddate = date('Y-m-d H:i:s');
$this->suratjalan->where('IDDeliveryNo',$id_sj);
$rec = $this->suratjalan->get("t02deliveryno_d")->result_array();
foreach ($rec as $det) {
$details = array(
'NoKwitansi' => $nokw,
'TypeProduct'=> $det['TypeProduct'],
'PartNo' => $det['PartNo'],
'PartNoVendor'=> $det['PartNoVendor'],
'SerialPanel' => $det['SerialPanel'],
'Description' => $det['Description'],
'Dimension' => $det['Dimension'],
'DescriptionVendor' => $det['DescriptionVendor'],
'DimensionVendor' => $det['DimensionVendor'],
'PrintedProduct' => $det['PrintedProduct'],
'Qty' => $det['Qty'],
'UoM' => $det['UoM'],
'Remark' => $det['Remark'],
'UpdUser'=> $this->session->userdata('user'),
'UpdDate'=> $upddate
);
$this->finance->insert('t02fkpd',$details);
}
}
Beyond removing the ID value, I also made the following minor changes:
I removed $i and just reused the same variable for building the array of values to insert. You're not using the array after you insert, so there's no need to build a list of all the rows - you can just overwrite it each time.
I changed your the $upddate calculation to only call date() once. You can specify an entire format string in one call - you're not restricted to just a single character at a time.
I haven't get your question properly. But i think http://ellislab.com/codeigniter/user-guide/database/active_record.html#insert with definitely help you.
You can make a array and pass it to insert_batch function with the table name and array. This will definitely help you.
if you must have checked user-guide for codeigniter. its one of the good documentation, where each and every function is documented.
Related
I'm using CodeIgniter framework for the easyappointments.org library. I'm trying to update the field data through the id of a row. Actually this is my code for the update:
return $this->db
->update('ea_appointments', $appointment)
->where('ea_appointments.id', $appointment_id);
The problem's that the update method need two parameter (table to update, associative array with the fields name column of db). In my above function I pass only the $appointment_id, so the variable $appointment is empty and doesn't contain any associative array. I want to know how to update only the field data to 1. And remain the other field in the same value condition.
This is the structure of the table:
id|book|start|end|notes|hash|unavailable|provider|data
Logic example:
previous condition row:
id => 0
book => example
start => 18/10/2015
end => 19/10/2015
notes => empty
hash => akdjasldja
unavailable => false
provider => 5
data => 0
I pass in the function $appointment_id with 0 value. I'm waiting this new result:
id => 0
book => example
start => 18/10/2015
end => 19/10/2015
notes => empty
hash => akdjasldja
unavailable => false
provider => 5
data => 1
So the main problem is retrieve first the all field value of the specific row and later update? Or something like this. Could someone help me?
In my above function I pass only the $appointment_id, so the variable
$appointment is empty and doesn't contain any associative array.
If you simply want to update the column data to 1 for appointment_id 0 then pass in an array with data for the key and 1 for the value.
$appointment_id = 0;
$appointment = array('data' => 1);
$this->db->where('id', $appointment_id);
$this->db->update('ea_appointments', $appointment);
I have a query that populates an array from the database. In some cases, this query returns a great amount of data, (let's say for purpose of an example, 100.000 records). Each row of the database has at least 6 or 7 columns.
$results = [
['id' => 1, 'name' => 'name', 'status' => true, 'date' => '10-01-2012'],
['id' => 2, 'name' => 'name 2', 'status' => false 'date' => '10-01-2013'],
...
]
I need to perform a substitution of some of the data inside the $results array, based on another one that give me some information about how i would change the values in the rows.
$model = [
'status' => ['function' => 'formatStatus', params => ['status']],
'date' => ['function' => 'formatDate', params => ['date']]
]
Now that i have all the data and what do i do with it i have the following routine.
foreach ($results as &$itemResult) {
$oldValues = $itemResult;
foreach ($itemResult as $attribute => &$value) {
if (isset($model[$attribute]['function'])) {
$function = $model[$attribute]['function'];
$params = $model[$attribute]['params'];
$paramsSize = count($params);
for ($i = 0; $i < $paramsSize; $i++) {
$newParams[] = $oldValues[$params[$i]];
}
$itemResult[$attribute] = call_user_func_array([$this, $function], $newParams);
$newParams = null;
}
}
}
So, for each attribute for each row of my data array, i run check for the existence of a function and params information. When the attribute in question needs to be replaced, i call the function via call_user_func_array and replace the value with the function return value.
Also notice that i am replacing the current array, not creating another, by passing the reference &$itemResult inside the loop, so in the end, i have the same array from the beginning but with all columns that needed to be replaced with its new values.
The thing is, for little arrays, this method is quite good. But for big ones, it becomes a pain.
Could you guys provide me some alternative to the problem?
Should i use another data structure instead of the PHP array?
The Problem/How
Pass angularJS the array result of a query that includes many joins.
Using angularJS to sort with ui-sortable reorders the dataset when sorting.
Pass data back to PHP and use synchronizeWithArray to save back (creates a collection).
Doctrine doesn't like receiving the data of the collection back in a different order than it outputs.
** If all I change are values - without reordering elements it saves with no problems.
Update: http://www.doctrine-project.org/jira/browse/DC-346
Noticed it was an old bug they never fixed, is there anything to still do what I want?
Details
$model = Doctrine_Core::getTable('TableName')->findOneById(...);
$model->synchronizeWithArray(array);
$model->save();
Doctrine (1.2) / mysql throws an Integrity error, duplicate primary key id = 2 - it is trying to change the id field.
When I reorder the elements with ui-sortable, it moves the arrays within 'Fields' around while also updating the 'position' value.
This is example data:
The problem would be array 0 and array 1 swap places - causing doctrine to cause primary key error as it tries to change the ids over.
array( // the root of the array is part of one table
id => 1001,
label => 'xxx',
Fields => array( // related table data
0 => array(
id => 1,
position => 0,
name => 'item1'
),
1 => array(
id => 2,
position => 1,
name => 'item2'
),
2 => array(
id => 3,
position => 2,
name => 'item3'
),
3 => array(
id => 4,
position => 3,
name => 'item4'
)
)
)
Well I guess we could either look on the Doctrine side and try to fix this bug, or make it work with the way Doctrine operates. The second option is probably easier.
Why don't you just save the order of the data, and put it back in that order before feeding it back to doctrine? One way to do that would be in angular. Where ever you get the array of data in angular, call saveOrder(), and before feeding it back, call reOrder():
var order = {};
function saveOrder(data)
{
for(var key in data)
{
if(data.hasOwnProperty(key))
{
order[data[key].id] = key;
}
}
}
function reOrder(data)
{
var ordered = [];
for(var key in data)
{
if(data.hasOwnProperty(key))
{
ordered[order[data[key].id]] = data[key];
}
}
return ordered;
}
We have some customer data which started in a separate data-store. I have a consolidation script to standardize and migrate it into our core DB. There are somewhere around 60,000-70,000 records being migrated.
Naturally, there was a little bug, and it failed around row 9k.
My next trick is to make the script able to pick up where it left off when it is run again.
FYI:
The source records are pretty icky, and split over 5 tables by what brand they purchased ... IE:
create TABLE `brand1_custs` (`id` int(9), `company_name` varchar(112), etc...)
create TABLE `brand2_custs` (`id` int(9), `company_name` varchar(112), etc...)
Of course, a given company name can (and does) exist in multiple source tables.
Anyhow ... I used the ParseCSV lib for logging, and each row gets logged if successfully migrated (some rows get skipped if they are just too ugly to parse programatically). When opening the log back up with ParseCSV, it comes in looking like:
array(
0 => array( 'row_id' => '1',
'company_name' => 'Cust A',
'blah' => 'blah',
'source_tbl' => 'brand1_cust'
),
1 => array( 'row_id' => '2',
'company_name' => 'customer B',
'blah' => 'blah',
'source_tbl' => 'brand1_cust'
),
2 => array( 'row_id' => '1',
'company_name' => 'Cust A',
'blah' => 'blah',
'source_tbl' => 'brand2_cust'
),
etc...
)
My current workflow is along the lines of:
foreach( $source_table AS $src){
$results = // get all rows from $src
foreach($results AS $row){
// heavy lifting
{
}
My Plan is to check the
$row->id and $src->tbl combination
for a match in the
$log[?x?]['row_id'] and $log[?x?]['source_tbl'] combination.
In order to achieve that, I would have to do a foreach($log AS $xyz) loop inside the foreach($results AS $row) loop, and skip any rows which are found to have already been migrated (otherwise, they would get duplicated).
That seems like a LOT of of looping to me.
What about when we get up around record # 40 or 50 thousand?
That would be 50k x 50k loops!!
Question:
Is there a better way for me to check if a sub-array has a "row_id" and "source_tbl" match other than looping each time?
NOTE: as always, if there's a completely different way I should be thinking about this, I'm open to any and all suggestions :)
I think that you should do a preprocessing on the log doing a hash (or composed key) of row_id and source_tbl and store it in an hashmap then for each row just construct the hash of the key and check if it is already defined in the hashmap.
I am telling you to use hashed set because you can search in it with O(k) time otherwise it would be the same as you are proposing only that it would be a cleaner code.
I'm not familiar with CakePHP too close. Recently I've ran into problem using Model. I need to get exaclty one row from database, modify some columns values and save it back. Pretty simple, right?
What do I try to do:
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findFirst($condition);
BUT i get FALSE in $model variable. At hte same time
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findAll($condition);
returns array. Its structure is something like:
array (
0 =>
array (
'MyModel' =>
array (
'id' => '1',
'some_id_column' => '123456',
'some_field' => 'some text',
...
),
),
I'd go with findAll if it did not return an array of arrays, but array of models (in my case - of one model). What do I want to achieve:
$condition = array('some_id_column' => $another_models_id);
$model = $this->MyModel->findFirst($condition);
$model->some_field = 'some another text';
$model->save();
Could you help me out to understand how it's usually done in CakePHP?
I'd also like to hear why findAll finds row and findFirst fails to find it... It just does not make sense to me... They should work in almost the same way and use the same database APIs...
If I can not do what I want in CakePHP, would you write a receipt how it is usually done there ?
There is no such method as findFirst.
You're probably looking for find('first', array('conditions' => array(...))).