CakePHP - Why does Model::save cause() an INSERT instead of an UPDATE? - php

I want to update database in CAKEPHP's Way
this is my controller
$data = array(
'KnowledgeBase' => array(
'kb_title' => $this->data['KnowledgeBase']['kb_title'],
'kb_content' => $this->data['KnowledgeBase']['kb_content']
'kb_last_update' => date("Y-m-d G:i:s"),
'kb_segment' => $this->data['KnowledgeBase']['kb_segment']
));
$this->KnowledgeBase->id_kb = $this->data['KnowledgeBase']['id_kb'];
$this->KnowledgeBase->save($data);
assume I have post form is true, when I execute the program
I have some error like this :
Database Error
Error: SQLSTATE[23000]: [Microsoft][SQL Server Native Client 10.0]
[SQL Server]Violation of PRIMARY KEY constraint 'PK_cnaf_kb'.
Cannot insert duplicate key in object 'dbo.cnaf_kb'.
SQL Query: INSERT INTO [cnaf_kb] ([kb_judul], [kb_segment], [kb_isi], [id_kb], [kb_last_update], [kb_status]) VALUES (N'HARRIS TEST 4 ', N'4', N'<p>TESSSSSSSSSSSSSSSSSSSSSS</p> ', 73,
'2013-10-04 16:57:00', 1)
why the function use the insert query? not update ?
note : im not using form helper for post to controller, and I use Cakephp 2.3.8 version and sql server 2008 for database
Im sorry for my bad english, I hope someone can help me :(((

You do not supply a primary key value, that's why.
No matter what your primary key is named (Model::$primaryKey), on the model object you have to use the id property (Model::$id) if you want to set the primary key value.
$this->KnowledgeBase->id = $this->data['KnowledgeBase']['id_kb'];
Internally the model maps this to the appropriate primary key field.
In the data however you'd use the actual primary key name:
'id_kb' => $this->data['KnowledgeBase']['id_kb']
btw, I'm not sure why you are (re)building the data array, but if it's to make sure that only specific fields are saved, then you could use the fieldList option instead:
$this->data['KnowledgeBase']['kb_last_update'] = date('Y-m-d G:i:s');
$options = array(
'fieldList' => array(
'kb_title',
'kb_content',
'kb_last_update',
'kb_segment'
)
);
$this->KnowledgeBase->save($this->data, $options);

Related

A Database Error Occurred Duplicate entry '119867-en_GB' for key 'PRIMARY'

I am using codeigniter to insert data from my page to a database , and i get this error
<h1>A Database Error Occurred</h1>
<p>Error Number: 1062</p><p>Duplicate entry '119867-en_GB' for key 'PRIMARY'</p><p>INSERT INTO `ProjectTableName` (`id`, `lang`, `name`) VALUES (119867, 'en_GB', 'test data')</p><p>Filename: models/modelFileLocation.php</p><p>Line Number: 48</p> </div>
Here is my code in the model for insertion of data to the database
$this->db->insert('ProjectTableName', array('id' => $table_id,
'lang' => $lang,
'name' => $name));
How can i be able to solve this error , am using codeignter 3
you not need to send id in the insert array. remove it from the array and make it auto increment in the database. Just use the below code
$this->db->insert('ProjectTableName', array(
'lang' => $lang,
'name' => $name));
If you want to make sure that data is returned, you can also use these codes,
$data = [
'lang' => $lang,
'name' => $name,
];
$this->db->set($data)->insert('ProjectTableName');
if($this->db->affected_rows() > 0) {
return true;
} else {
return false;
}
The number of columns interacting in this way will return, and if true is greater than 0, it will return true.
I'm sure your problem is definitely caused by what I wrote below.
The 'lang' field in the table is selected as 'primary key' and the primary key fields accept only one of the data.
The right example
lang
----
a
b
c
d
If your table situation is this and wrong
lang
----
a -> 1
a -> 2
c
d
cannot contain two 'a' data in the primary key field, specify an id instead and set it as primary key. there is a repetitive entry in the primary key field as the error says.
Good work ..

php yii2 how to make automaticly id in query yii2 insert?

i have a code like this ,
$request = Yii::$app->request;
$post = $request->post();
$filesettingid = $post['filesettingid'];
$checkboxValue = $post['selection'];
for($i=0;$i<sizeof($checkboxValue);$i++) {
$store = Yii::$app->db->createCommand('SELECT id FROM store WHERE port='.$checkboxValue[$i])->queryAll();
$storeid = $store[$i]['id'];
Yii::$app->db->createCommand()->insert('tes',
[
'id' => $i+1,
'filesetting_id' => $filesettingid,
'store_id' => $storeid
])->execute();
}
what i want is, each i insert the new data, id will generate automaticly like 1,2,3,4.
the problem in above code is, the ID always be 1.
is it possible to make it real?
so what i want is :
First time insert, id = 1, second is id = 2 , and that is happen automatically.
Have you considered setting database engine to auto increment values with each insert?
Take as an example Yii2 default user table. ID filed is auto incremented, and you don't have to worry about setting it problematically. Every time you send a new insert engine increments ID filed by itself.
See default migration under "advanced template"\console\migrations\m130524_201442_int. (your file name might be different depending on the Yii2 version)
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),
'status' => $this->smallInteger()->notNull()->defaultValue(0),
.........
], $tableOptions);
When setting 'id' to primary key database automatically knows to auto increment it. If you already have a table the ID field is not primary key you can use the followign migration:
$this->alterColumn('{{%databaseName}}', 'columnName', $this->integer()->notNull().' AUTO_INCREMENT');
You can also set it from management console, or run a SQL query. Depending on database engine you are using this might look a little different but the concept is the same.
MYSQL:
In MySQL workbench right click on table in question, select Alter Table and check NNm and AI next to column you want auto increment. See Screenshot
Or run command:
ALTER TABLE `dbName`.`nameOfTheTable` MODIFY `columnName` INT AUTO_INCREMENT NOT NULL;
I am a bit rusty on my SQL, so if it does not work let me know I will get you right command.
Hope this helps. Good luck.

How insert data to Cassandra DB via library php?

I use Cassandra-PHP-Client-Library library for get/set data to Apache Cassandra.
I created a keyspace name via cqlsh coomanda line:
CREATE TABLE employees (
company text,
name text,
age int,
role text,
PRIMARY KEY (company,name)
);
Then have inserted some columns also via command line:
INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'eric', 38, 'ceo');
INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'john', 37, 'dev');
Now I try insert any data from php, for this i use method set() of library:
$this->cassandra->set(
'employees.company',
array(
'company' => 'alicerozenberg#gmail.com',
'name' => 'Alice Rozenberg',
'age' => 45,
'role' => 'ddd'
)
);
In the official manual was told that first param of function set() is key row (employees is a name of column family, company is a key), and other - are name and value of columns.
In this regard, I have a few questions:
What is a row key in my case? At the "CREATE" command I specifed, that primary key is "company,name". But this not correct for use in function. This option does not work:
$this->cassandra->set(
'employees.name',
...
$this->cassandra->set(
'employees.company',
...
I change to phpcassa library and have question about composites types:
From tutorial example:
https://github.com/thobbs/phpcassa/blob/master/examples/composites.php
// Insert a few records
$key1 = array("key", 1);
$key2 = array("key", 2);
$columns = array(
array(array(0, "a"), "val0a"),
array(array(1, "a"), "val1a"),
array(array(1, "b"), "val1b"),
array(array(1, "c"), "val1c"),
array(array(2, "a"), "val2a"),
array(array(3, "a"), "val3a")
);
Who can me tell, what composire array will be in my case for two row keys "name, company"? Thank you!
PRIMARY KEY (company,name)
Compound primary keys in Cassandra have multiple parts. The first column (company in your case) is your partitioning key. This is the key that will help determine which partition the row is stored on.
The next part of a compound primary key, are the clustering columns. The clustering columns indicate the on-disk sort order of your data. In your case, you only have one clustering column (name). Your row data will then be stored by a (assumed unique) combination of company and name, and your data will be sorted (on-disk) by name.
What is a row key in my case?
The row key in your case is this combination of both company and name.
Now how do you set that in your PHP (PHPCassa?) code? I'm not exactly sure. But from what I'm reading on this blog posting (warning: it is a couple of years old) titled Cassandra PHPCassa & Composite Types, you may need to define your rowkey as an array, like this:
$this->cassandra->set(
array('employees.company','employees.name'),
array(
'age' => 45,
'role' => 'ddd'
)
);
Try that and see if it helps. Otherwise, reference the article I linked above.
Based on your most-recent edit, I think your key definition will look something like this:
$key = array("alicerozenberg#gmail.com", "Alice Rozenberg");
$columns = array(45,"ddd");
$cf->insert($key, $columns);

Eloquent update() failing due to updated_at table ambiguity

Ok, this question stems from a Laravel 4.1.23 install. I'm attempting to update multiple records using the Eloquent update() method on a query that includes a join:
ChildSchoolYear::whereNull('exit_date')->
join('school_years', 'child_school_years.school_year_id','=','school_years.id')->
update(array('child_school_years.exit_date'=>'`school_years`.`end_date`',
'child_school_years.editor_id'=>$userId))
Laravel is generating the correct SQL for the query content I'm providing above, but the full SQL statement generated is
update `child_school_years`
inner join `school_years` on `child_school_years`.`school_year_id` = `school_years`.`id`
set `child_school_years`.`exit_date` = `school_years`.`end_date`,
`child_school_years`.`editor_id` = 2,
`updated_at` = 2014-08-15 02:00:33 where `exit_date` is null)
This would work except that the automatically added updated_at field exists in both the child_school_years and school_years tables, so the addition of the field by Laravel triggers the Exception Integrity constraint violation: 1052 Column 'updated_at' in field list is ambiguous.
Any suggestions on how to domesticate the updated_at piece? I'd be happy to have the field updated, but I'll live without it if necessary should it be possible to eliminate it.
There is no way to alter Eloquent behaviour, even adjusting UPDATED_AT column won't help, so you need to use either simple Query\Builder, like already suggested, or one of the methods below, that I find a bit better:
// easiest way
ChildSchoolYear::whereNull('exit_date')
->join('school_years', 'child_school_years.school_year_id','=','school_years.id')
->getQuery() // get underlying base Query\Builder
->update(
array(
'child_school_years.exit_date' => '`school_years`.`end_date`',
'child_school_years.editor_id' => $userId,
'child_school_years.updated_at' => Carbon\Carbon::now(),
)
);
// also would work, temporary turn off auto timestamps
with($model = new ChildSchoolYear)->timestamps = false;
// above is the same as:
// $model = new ChildSchoolYear;
// $model->timestamps = false;
$model->whereNull('exit_date')
->join('school_years', 'child_school_years.school_year_id','=','school_years.id')
->update(
array(
'child_school_years.exit_date' => '`school_years`.`end_date`',
'child_school_years.editor_id' => $userId,
'child_school_years.updated_at' => Carbon\Carbon::now(),
)
);

Duplicate key error during upsert [Explanation]

I am executing the below statement in a class. This code is from
$query = array('_id' => $id, 'lock' => 0);
$update = array('$set' => array('lock' => 1));
$options = array('safe' => true, 'upsert' => true);
$result = $this->_mongo->update($query, $update, $options);
if ($result['ok'] == 1) {
return true;
}
However I do not understand how I would get a duplicate key error.
Can someone explain the possible scenarios and likelihood that I will receive this error?
I have been researching this extensively, cannot find my answer anywhere. So if it is on SO or any other website please share!
Thanks in advance.
Since you're doing an upsert and including _id in your query, you shouldn't be getting any duplicates on that key. This makes me think that you've created a unique index on lock, which isn't going to work for more than 2 documents because you only have 2 values for that field.
If you haven't put a unique index on lock, then you must have a unique index on a field you aren't showing here. That won't work either because on an insert, your upsert is going to set _id and lock only, any other field with an index will be inserted as null. If one of those fields has a unique index, then only a single document can have a null in that field. So when you try and insert another null for that field, you'll get a duplicate key error.

Categories