Cakephp save array data in MySql Database using loop with create - mysql

I am facing strange problem first time. I am trying to insert simple records in database with Custom Auto Increment Values e.g 00001, 00002, 00003. but unable to get Incremented value. Each record get updated with same max number.
Controller Code
public function dobulk() {
for($i=0;$i<5;$i++) {
$data = array();
$this->Tmp->create();
$data['Tmp']['invoice_no'] = $this->Tmp->get_no();
$data['Tmp']['invoice_date'] = '2013-12-11';
$this->Tmp->save($data);
}
}
Model Code
public function get_no() {
$strSql = "SELECT
LPAD(IFNULL(RIGHT(MAX(invoice_no),5),0) + 1,5,'0') AS max_id
FROM tmps
;";
$result = $this->query($strSql);
$invoice_no = $result[0][0]['max_id'];
return $invoice_no;
}
Database Table
CREATE TABLE `tmps` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_no` varchar(20) DEFAULT NULL,
`invoice_date` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
Thanks in advance.

You're probably running into the model cache.
From here: Bakery article on caching
If Model->cacheQueries == true, Cake will store the result of queries in memory. If it later sees an identical query, the result will be pulled from memory instead of hitting the database. This is only cached for the duration of a single page request. However, if a record is updated, the cache is not cleared. This is what gets most people unfamiliar with the cache.
So to make your code work, add this line to the top of the dobulk() function:
$this->Tmp->cacheQueries = false;
As you're running raw SQL inside your model, you might also have to change the query request inside get_no() to:
$result = $this->query($strSql, false);

Hope below solution will help you!
public function get_no() {
$strSql = "SELECT MAX(invoice_no) AS max_id FROM tmps;";
$result = $this->query($strSql);
$invoice_no = $result['Tmp']['max_id'];
return $invoice_no;
}
public function dobulk(){
$data = array();
$tempInvoiceNumber = $this->Tmp->get_no();
for($i=1;$i<=5;$i++) {
$data[$i]['Tmp']['invoice_no'] = tempInvoiceNumber+$i;
$data[$i]['Tmp']['invoice_date'] = '2013-12-11';
}
$this->Tmp->saveAll($data);
}

Related

Can I use AUTO_INCREMENT in my laravel project?

I have an Eloquent model that has a column that is a number composed of various codes and at the end a number that should increment automatically. This last number is the same number I use to define the primary key of my model, so my question is:
Is there a way to use the AUTO_INCREMENT variable from my MySQL database?
If not, what is the best way to create a variable in Laravel that automatically increments?
example:
$code1 = $this->getCode1();
$code2 = $this->getCode2();
$autoIncr = ...;
$final_code = $code1 . $code2 . $autoIncr;
you can create a function that returns the next id (autoincrement) of your table and the insert the entry in your table;
$code1 = $this->getCode1();
$code2 = $this->getCode2();
$autoIncr = $this->getNextAutoincrement();
$final_code = $code1 . $code2 . $autoIncr;
//Insert in your table
$row = YourModel::create([
'finalCode' => $final_code
]);
private function getNextAutoincrement() {
//don't forget import DB facade at the beginning of your class
$id = DB::select("SHOW TABLE STATUS LIKE 'YOUR_TABLE_NAME'");
$next_id=$id[0]->Auto_increment;
return $next_id;
}
Hope I've helped you

User defined PK on yii2

I am currently following the Yii2 start guide.
I am stumpted at the interacting with a database step.
I have created a database as they suggest with code as its primary key
CREATE TABLE `country` (
`code` CHAR(2) NOT NULL PRIMARY KEY,
`name` CHAR(52) NOT NULL,
`population` INT(11) NOT NULL DEFAULT '0'
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
I create a model and the CRUD methods using the gii generator.
The issue is that the generated code refers to id as a primary key at all times, not the case due to the suggested table structure, and even the findModel needs to be updated from.
protected function findModel($code)
{
if (($model = Country2::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
To
protected function findModel($code)
{
if (($model = Country2::findOne($code)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
Once updated the code works but the issue is with the gridview where every action has an id tacked on to it.
ie https://localhost/tutorialYii/web/index.php?r=country2%2Fview&id=12
rather than https://localhost/tutorialYii/web/index.php?r=country2%2Fview&code=12
I understand this can be fixed by using id as the primary key but I would like to understand how to address the issue of using a custom primary key rather than the standard one.
I have not modified the autogenerated code in any form.
The autogenerated code works for country2 which has id as its PK. I would like to understand how to adapt it so that it works for a PK that is not id.
Implement primarykey() in your model:
public static function primaryKey()
{
return ['code'];
}
Now you can use this:
YourModel::findOne($code);
and always use $model->getPrimarykey() instead $model->code for access to your primary key.

how to make updated_at the only column updating and not created_at

Every time I am updating a data in MYSQL, the created_at updates the same time as updated_at. I only want updated_at to be the only ones to be updating. is there anyway I can do this?
Laravel 4.2 - 5.1
here is my code in controller
public function read(){
$response = array();
$data = Docs::find(Input::get("id"));
if($data){
$data -> read = "1";
$data -> save();
$response["success"] = TRUE;
}
return Response::json($response);
}
Since there is nothing wrong with your code, it might be a problem with how the database was setup.
A common mistake is that the created_at column, in the database, is setup to be a timestamp that automatically updates when the table data changes.

Set a value to null, when calling Zend_Db::update() and insert()

My question is the exact same as How to Set a Value to NULL when using Zend_Db
However, the solution given in that question is not working for me. My code looks like the following. I call updateOper on the Model class when update is clicked on the front end. Inside updateOper, I call another function trimData() where I first trim all whitespace and then I also check that if some of the fields are coming in empty or '' I want to set them to default values or NULL values. Therefore I am using new Zend_db_expr('null') and new Zend_db_expr('default') .
The code is as follows:
private function trimData(&$data ) {
//Trim whitespace characters from incoming data.
foreach($data as $key => $val)
{
$data[$key] = trim($val);
if($data['notes'] == '') {
error_log("set notes to null/default value");
$data['notes'] = new Zend_db_expr('DEFAULT');
}
}
}
public function updateOper($data, $id)
{
$result = 0;
$tData = $this->trimData($data);
error_log("going to add data as ".print_r($data, true));
$where = $this->getAdapter()->quoteInto('id = ?', $id);
$result = $this->update($data, $where);
return $result;
}
The error_log statement prints the $data array as follows:
[id] => 10
[name] => alpha
[notes] => DEFAULT
As a result, the notes column has value ='DEFAULT' instead of picking the default value given in the table definition.
I have been trying to figure out what is wrong, but have not been able to find a solution.
I would really appreciate your help.
Thanks so much!
Your $data['notes'] is being changed to the __toString() value of the Zend_Db_Expr instead of preserving the actual object.
Maybe the reference is clogging things up. Else you may need to move the expression declaration into the actual update query.

why only first letter of column coming from mysql database in php?

my database is
CREATE TABLE `mytable` (
`id` int(10) AUTO_INCREMENT,
`name` varchar(50),
`description` varchar(255),
`visible` varchar(10),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET utf8;
and php code is
$display = query("SELECT * FROM mytable ORDER BY id ASC");
foreach($display as $row) {
echo $row['id'];
echo $row['name'];
echo $row['description'];
}
what is wrong in my code ? data is not displayed and when it display only first letter of field is displayed. All the configuration and connection settings are fine. Pls help
var_dump($row);
Looks like it's the same pitfall I fell into once :)
Don't you have only one row in your table?
If this query() function is kinda too smart one, determining return type by returned data, it can be a reason.
Make it return nested array, not one row.
And define result type explicitly, not automatically based on returned data. Add a parameter to indicate what kind of result you want.
However, such a function is very good approach. Only a few people have an idea of devising such a function instead of constant hassle with numerous API functions.
but if you expect just one row, then
$row = query("SELECT * FROM mytable ORDER BY id ASC");
echo $row['id'];
echo $row['name'];
echo $row['description'];
I had the this same problem using CodeIgniter.
The problem for me was that I was trying to echo out the array value using an associative key when it was just a numerically indexed array. I'm surprised it worked at all.
So my array was built like so:
$result = $this->ci->db->get('role');
if($result->num_rows() > 0)
{
foreach($result->result_array() as $row)
{
$roles[$row['id']] = $row['name'];
}
}
When I tried to use the array like so:
foreach($roles as $role)
{
echo $role['name'];
}
It would only print out the first letter of each value.
When I changed the array to be built like this:
$roles[$row['id']] = array('name' => $row['name']);
Everything worked as expected.
Hope this helps someone.