BEGIN,INSERT,COMMIT with ON DUPLICATE KEY UPDATE - mysql

I have two tables:
1- beoordelingen
2 - sterren
I need to update 3 values in table beoordelingen and insert new values into table sterren
How do I do that?
ON DUPLICATE KEY doesn't work and I can't find anywhere how to do it.
$sql=$dbo->prepare("BEGIN;INSERT INTO beoordelingen(beoordelingid,userid,werkid,inlijn,
sjabloon,conclusie,save)
VALUES ('$beoordelingid','$user','$werkid','$inlijn','$sjabloon','$conclusie','0')
ON DUPLICATE KEY UPDATE
beoordelingid=VALUES(beoordelingid),userid=VALUES(userid), werkid=VALUES(werkid),
inlijn=VALUES(inlijn),sjabloon=VALUES(sjabloon),conclusie=VALUES(conclusie),
save=VALUES(save);
INSERT INTO sterren (beoordelingid,userid,werkid,titelwerk,actie,sterren)
VALUES ('$beoordelingid','$user','$id','$titelwerk',
'$actie','$sterren'); COMMIT");
I adapted the following. The insert1 still won't work. Insert2 works
$dbo->beginTransaction();
//NOT WORKING
$insert1 = $dbo->prepare("INSERT INTO beoordelingen(beoordelingid, userid, werkid, inlijn, sjabloon, conclusie, save)
VALUES (:beoordelingid, :user, :werkid, :inlijn, :sjabloon, :conclusie, '0')
ON DUPLICATE KEY UPDATE
beoordelingid=VALUES(beoordelingid),
userid=VALUES(userid),
werkid=VALUES(werkid),
inlijn=VALUES(inlijn),
sjabloon=VALUES(sjabloon),
conclusie=VALUES(conclusie),
save=VALUES(save);"
);
//THIS WORKS
$insert2 = $dbo->prepare("INSERT INTO sterren (beoordelingid, userid, werkid, titelwerk, actie, sterren)
VALUES (:beoordelingid, :user, :id, :titelwerk, :actie, :sterren);"
);
//NOT WORKING
$insert1->execute(array(
'beoordelingid' => $beoordelingid,
'user' => $user,
'werkid' => $werkid,
'inlijn' => $inlijn,
'sjabloon' => $sjabloon,
'conclusie' => $conclusie,
'save' => $save
));
//THIS WORKS
$insert2->execute(array(
'beoordelingid' => $beoordelingid,
'user' => $user,
'id' => $werkid,
'titelwerk' => $titelwerk,
'actie' => $actie,
'sterren' => $sterren
));
$dbo->commit();
My last problem:
$sterren=$_POST['sterren'];
$user=$_REQUEST['user'];
$userid=$_POST['userid'];
$actie=$_POST['actie'];
$dbo->beginTransaction();
//THIS WORKS
$insert1 = $dbo->prepare("INSERT INTO sterren(sterren,userid,actie)
VALUES (:sterren, :userid, :actie);"
);
//THIS DOESN"T WORK
$insert2 = $dbo->prepare("INSERT INTO sterren(sterren,userid,actie)
VALUES (:-sterren, :user, :actie);"
);
//THIS WORKS
$insert1->execute(array(
'sterren' => $sterren,
'userid' => $userid,
'actie' => $actie
));
//THIS DOESN"T WORK
$insert2->execute(array(
'-sterren' => $sterren,
'user' => $user,
'actie' => $actie
));
$dbo->commit();

This is not how to use prepared statements (->prepare()) or how to use a transaction with PDO.
First off, prepare() is for "preparing" one SQL query with placeholders so that you can pass the parameters in a later function (execute()) and avoid SQL injection from concatenating strings.
Second, if you want to use a transaction then you should use PDO's beginTransaction and commit functions.
Try something like this:
$dbo->beginTransaction();
$insert1 = $dbo->prepare('INSERT INTO beoordelingen(beoordelingid, userid, werkid, inlijn, sjabloon, conclusie, save)
VALUES (:beoordelingid, :user, :werkid, :inlijn, :sjabloon, :conclusie, :save)
ON DUPLICATE KEY UPDATE
beoordelingid=VALUES(beoordelingid),
userid=VALUES(userid),
werkid=VALUES(werkid),
inlijn=VALUES(inlijn),
sjabloon=VALUES(sjabloon),
conclusie=VALUES(conclusie),
save=VALUES(save);'
);
$insert2 = $dbo->prepare('INSERT INTO sterren (beoordelingid, userid, werkid, titelwerk, actie, sterren)
VALUES (:beoordelingid, :user, :id, :titelwerk, :actie, :sterren);'
);
$insert1->execute(array(
'beoordelingid' => $beoordelingid,
'user' => $user,
'werkid' => $werkid,
'inlijn' => $inlijn,
'sjabloon' => $sjabloon,
'conclusie' => $conclusie
));
$insert2->execute(array(
'beoordelingid' => $beoordelingid,
'user' => $user,
'id' => $id,
'titelwerk' => $titelwerk,
'actie' => $actie,
'sterren' => $sterren
));
$dbh->commit();

Related

Codeigniter Insert Data MSSQL

I am working website with multiple database and it use both MSSQL and MYSQL but I dont why insert data wont work. I have 2 codes sample below:
1st MODEL code
$this->mssqlu->insert('tbl_account', array('id ' => CONVERT(BINARY(16),$username, 1), 'password' => CONVERT(BINARY(16),$password, 1), 'Email' => $email, 'accounttype' =>0, 'birthdate' => '2011-11-11 00:00:00','pin' => $pin, 'fb_id' => $fb_id ));
return $this->mssqlu->insert_id();
2nd MODEL Code
$lu_sql = sprintf("INSERT INTO tbl_account (id,password,Email,accounttype,birthdate,pin,fb_id) VALUES ((CONVERT (binary,$username)),(CONVERT (binary,$password)),$email,0,'2011-11-11 00:00:00',$pin,$fb_id)");
$query = $this->mssqlu->query($lu_sql);
return $query;
$data=array('id ' => CONVERT(BINARY(16),$username, 1), 'password' =>
CONVERT(BINARY(16),$password, 1), 'Email' => $email, 'accounttype'
=>0,'birthdate' => '2011-11-11 00:00:00','pin' => $pin, 'fb_id' =>
$fb_id );
return (($this->mssqlu->insert('tbl_account', $data)) ? $this->mssqlu->insert_id() : False);

Update Rows, column values represent as keys

Here's the overview of my table.
The thing is, the value of meta_key column represent as keys.
The problem is, how would I update the fields with user_id. For example, I want to update gender, employee_type, division, mobile that has a different values each field that has a user_id of 1.
I really have no idea how though, but on Eloquent there's this ->insert() to insert multiple values.
$meta_values = [
['user_id' => $user->id, 'meta_key' => 'mobile', 'meta_value' => $mobile,],
['user_id' => $user->id, 'meta_key' => 'address', 'meta_value' => $address,],
['user_id' => $user->id, 'meta_key' => 'gender', 'meta_value' => $gender],
['user_id' => $user->id, 'meta_key' => 'birthday', 'meta_value' => Carbon::parse($birthday)->format('Y-m-d')],
['user_id' => $user->id, 'meta_key' => 'employee_type', 'meta_value' => $employee_type],
['user_id' => $user->id, 'meta_key' => 'division', 'meta_value' => $division],
['user_id' => $user->id, 'meta_key' => 'date_employed', 'meta_value' => Carbon::parse($date_employed)->format('Y-m-d')],
['user_id' => $user->id, 'meta_key' => 'avatar', 'meta_value' => $images->avatar]
];
$user->userMeta()->insert($meta_values);
Here's the insert version, but how's the update version going to be or what it looks like. Any ideas?
I think it would be possible by using loop, but I probably think that it would not be a great idea.
--- EDITED ---
For now, here's my temporary solution. Here's what I'm gonna do in the first place but, until someone has an answer to this problem, this is my solution for now.
//List all fields in an array to be updated
$meta_array = ['mobile', 'address', 'gender', 'birthday', 'employee_type', 'division', 'date_employed'];
for ($i = 0; $i < count($meta_array); $i++) {
$user->userMeta()
->where('meta_key', $meta_array[$i])
->update(['meta_value' => ${$meta_array[$i]}]);
}
Something along this lines should work for you:
$meta_array = array('gender', 'employee_type', 'division', 'mobile');
Your\Model::where('user_id', 1)
->whereIn('meta_key', $meta_array)
->update(['meta_value' => 'some_new_value']);
The above PHP code should correspond to the following raw SQL query which you gave in your question as an example:
UPDATE your_table
SET meta_value='some_new_value'
WHERE user_id=1 AND meta_key IN ('gender', 'employee_type', 'division', 'mobile')

CakePHP counterCache joining irrelevant tables to update counter

I have a User model and a Message model.
The Message model is linked to the User model twice like this:
public $belongsTo = array(
'UserSender' => array(
'className' => 'User',
'foreignKey' => 'sender_id',
'counterCache' => array(
'messages_sent_count' => array(
'is_deleted' => FALSE
)
)
),
'UserRecipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id',
'counterCache' => array(
'messages_received_count' => array(
'is_deleted' => FALSE
),
'messages_unread_count' => array(
'is_deleted' => FALSE,
'is_read' => FALSE
)
)
),
'Operator' => array(
'className' => 'Operator',
'foreignKey' => 'operator_id'
)
);
Besides the User model, the Message model also $belongsTo the Operator model. The Operator model is irrelevant to the message count for the users, but its table is still being joined in the count query, as debug shows:
'query' => 'SELECT COUNT(*) AS `count` FROM `database`.`messages` AS `Message` LEFT JOIN `database`.`operators` AS `Operator` ON (`Message`.`operator_id` = `Operator`.`id`) LEFT JOIN `database`.`users` AS `UserSender` ON (`Message`.`sender_id` = `UserSender`.`id`) LEFT JOIN `database`.`users` AS `UserRecipient` ON (`Message`.`recipient_id` = `UserRecipient`.`id`) WHERE `Message`.`is_deleted` = '0' AND `Message`.`sender_id` = 389',
'params' => array(),
'affected' => (int) 1,
'numRows' => (int) 1,
'took' => (float) 394
For the sake of simplicity I've actually excluded one more model that the Message model $belongsTo, but the above query shows the problem.
The counterCache function does a quite expensive query just to update the counter. Is there a way to maybe override or adjust the counterCache method to not join irrelevant tables in the query?
I can't test it right now, but since the recursive setting used by Model::updateCounterCache() is hard-coded based on whether conditions are defined for the counter cache field, the only way to change this (besides completely reimplementing Model::updateCounterCache()) is probably to modify the count query in Model::_findCount() or Model::beforeFind() of your Message model.
public function beforeFind($query) {
// ... figure whether this is the count query for updateCounterCache,
// maybe even try to analyze whether the passed conditions require
// joins or not.
if(/* ... */) {
$query['recursive'] = -1;
}
return $query;
}
Depending on how much control you'll actually need the containable behavior might do the trick too, it sets recursive to -1 in case no containments are being passed
$Message->contain(); // === recursive is being set to -1 in before find callback
$Message->delete(123);

How to find the latest record in cakephp?

I've got a a table with a column request_time. There will be multiple requests and I want to get the latest request of a particular username:
$this->Requests->find('all', 'conditions' => array (
'username' => $username,
'MAX'=> 'request_time'));
The above doesn't work. Is there something in Cakephp or do I need to do my own ->query()?
You can use the following:
$this->Requests->find('first', array('conditions' => array('username' => $username),
'order' => array('id' => 'DESC') ));
Where id is the auto incremented primary key.
This will give you the latest (single) record, if you are using first in find method, or else use all instead.
If you are not using primary key, you can try the following:
$this->Requests->find('first', array('conditions' => array('username' => $username),
'order' => array('request_time' => 'DESC') ));
If you have auto-incremented primary key then you find the latest record of this table try this
$this->Requests->find('find', 'conditions' => array ('username' => $username),
'order' => array('id' => 'DESC')
);

Retrieving Data From two tables that are associated with a forign key in CakePhp

I have two tables named login and userDetail
Login
login_id
uname
pswd
userdetail_id
and
userdetails
userdetail_id
name
address
email
the login table contain userdetails_id in the userDetail table. i want to get all data from Login table and userDetail table and save it to a variable
if anyone knows, please answer me......
First of all your table structure must be as below.
logins Table.
Id auto_increment
username
password
userDetails Table.
Id auto_increment
user_id
name
address
etc...
Now model for each table would be.
Login
<?php
class Login extends AppModel
{
var $name = 'User';
var $hasMany = array
(
'UserDetail' => array
(
'className' => 'UserDetail',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
}
?>
UserDetail
<?php
class UserDetail extends AppModel
{
var $name = 'UserDetail';
var $belongsTo = array
(
'User' => array
(
'className' => 'User',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => ''
)
}
?>
And finally in controller where you need to fetch login detail.
$login_detail = $this->Login->find('all');
You will see userDetail table records in resulting $login_detail.
use pr($login_detail); in controller to see it in action.
Cheers.
Feel Free to ask.
Make sure ContainableBehavior has been enabled. After that you can use following query:
$login = $this->Login->find('first', array(
'contain' => array(
'Userdetail.userdetail_id'
'Userdetail.name',
'Userdetail.address',
'Userdetail.email'
),
'fields' => array(
'Login.login_id'
'Login.uname',
'Login.pswd'
),
'conditions' => array(
'Login.login_id' => 1
)
));
The query for this task would be:
SELECT Login.*, name,address,email
FROM Login JOIN userdetails
ON Login.userdetail_id=userdetails.userdetail_id
The results of this query could be saved to variables by looping in cakephp.