Trigger not updating - php

I have a trigger that looks like this:
CREATE TRIGGER findavg after INSERT
ON rating
FOR EACH row
UPDATE `profile`
SET userscore = (SELECT Avg(rscore)
FROM rating
WHERE `profile`.`pid` = rating.raterid)
WHERE pid = new.pid;
where
PROFILE table - pID, name, userScore
RATING table - raterID, rScore, rDescription
It works at the first time I implemented this trigger, however yesterday I dropped all the data in both Profile and Rating table. Thus, I inserted a "freshly new" data for profile and rating.
Now everytime I insert a "RATING", the trigger won't update the userScore.
So right now, I have some PROFILE that have "0" in userScore, even though in RATING table the value is "6" for the rScore.
I'm confused because I'm pretty sure based on syntax, it's correct already.
Help me please. Thank you.

Try:
DELIMITER //
CREATE TRIGGER `findavg` AFTER INSERT ON `rating`
FOR EACH ROW
BEGIN
UPDATE `profile`
SET `userscore` = (SELECT AVG(`rscore`)
FROM `rating`
WHERE `raterid` = `pid`)
-- WHERE `pid` = NEW.`pid`;
WHERE `pid` = NEW.`raterid`;
END//
DELIMITER ;
SQL Fiddle demo

Related

MySQL Update activity when selecting user details

Table:
userid, sessionid, last_active
I got the following requests:
SELECT `userid` FROM `session_keys` WHERE `sessionid`='SESSION_ID'
UPDATE `session_keys` SET `last_active`=now() WHERE `sessionid`='SESSION_ID'
Is it possible to put it in one request? but I need the callback from the select request.
The only goal i wanna reach is to update the last_active time of an timestamp when selecting the data.
Thank you.
try:
SET #session_id = 'SESSION_ID';
SELECT `userid` INTO #sid FROM `session_keys` WHERE `sessionid` = #session_id;
UPDATE `session_keys` SET `last_active`=now() WHERE `sessionid` = #session_id;
SELECT #sid;
Could you give more context?
Try this query.
UPDATE
'tableA' AS 'A',
(
SELECT
*
FROM
'tableB'
WHERE
'id' = x
) AS 'src'
SET
'A'.'col1' = 'src'.'col1'
WHERE
'A'.'id' = x
;
Maybe this will be helpful:
Select and Update in same query (I know that you have the same table in both queries)
mysql select and update using one query in this case?

mysql insert record not immediately available, select count(*) doesn't see it right away

In my php code, I have a Mysql query:
SELECT COUNT(*)
to see if the record already exists, then if it doesn't exist I do an:
INSERT INTO <etc>
But if someone hits reload with a second or so, the SELECT COUNT(*) doesn't see the inserted record.
$ssql="SELECT COUNT(*) as counts FROM `points` WHERE `username` LIKE '".$lusername."' AND description LIKE '".$desc."' AND `info` LIKE '".$key."' AND `date` LIKE '".$today."'";
$result = mysql_query($ssql);
$row=mysql_fetch_array($result);
if ($row['counts']==0) // no points for this design before
{
$isql="INSERT INTO `points` (`datetime`,`username`,`ip`,`description`,`points`,`info`, `date`,`uri`) ";
$isql=$isql."VALUES ('".date("Y-m-d H:i:s")."','".$lusername."',";
$isql=$isql."'".$_SERVER['REMOTE_ADDR']."','".$desc."','".$points."',";
$isql=$isql."'".$key."','".$today."','".$_SERVER['REQUEST_URI']."')";
$iresult = mysql_query($isql);
return(true);
}
else
return(false);
I was using MyISAM database type
Instead of running two seperate queries just use REPLACE INTO.
From the documentation:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.
For example if your key field is id then:
REPLACE INTO my_table SET id = 4 AND other_field = 'foobar'
will insert if there is no record with id 4, or if there is then it will replace the other_field value with foobar.

Use inserted id for another column value

I have an identity column (id) that auto-increments.
id|name|image_path
I want to know if there is some way using mysql, to use the newly inserted id in the image_path.
For example if a new row is inserted and got the id 2 I want the image_path to be "/images/2.png".
Or do I have to use the traditional way, by inserting and then fetching this ID then updating the entry?
My opinion is that it is impossible to do with one query. You won't know new autoincrement value until row will be inserted. Still you can write 1 query to achieve what you want (actually 2 queries would be executed):
insert into `t`(`id`, `name`, `image_path`)
values(
(SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES
WHERE `table_name` = 't'),
'1234',
concat(
'/images/',
(SELECT `auto_increment` FROM INFORMATION_SCHEMA.TABLES
WHERE `table_name` = 't'),
'.png'
)
)
Anyway much safer would be:
START TRANSACTION;
set #c = (select ifnull(max(`id`),0) + 1 from `t`);
insert into `t`(`id`, `name`, `image_path`) values (#c,'123',concat('/images/',#c,'.png'));
COMMIT;
Yes, it is possible with oracle. We have dynamic sql feature.
have tried the below.
Created a sequence and then created a procedure which takes id as input and creates an insert statement dynamically which will fulfill your requirement.
create sequence seq1 start with 1;
create table image1(id1 number,image varchar2(50));
create or replace procedure image1_insert(id1 in number)
as
sql_stmt varchar2(50);
image_path varchar2(50);
begin
sql_stmt:='insert into image1 values(:1,:2)';
image_path:='/image/'||id1||'.png';
execute immediate sql_stmt using id1,image_path;
end;
begin
image1_insert(seq1.nextval);
end;
id image
4 /image/4.png
5 /image/5.png
select *from image1;

PHP Insert or update table

Let me explain what I need and canot get :(
I have to DB one i main the other is just getting part of data from the firs one.
This is my code:
foreach($id_product_array AS $id_product) {
$resultf = mysql_query("SELECT * FROM db1_available_product WHERE id_product='".$id_product."'");
while($rowi = mysql_fetch_array($resultf)) {
$aa1=$rowi['id_product'];
$aa2=$rowi['date'];
$aa3=$rowi['available'];
$aa4=$rowi['published'];
mysql_query("INSERT INTO aa_bb.db2_available_product (`id_product`, `date`, `available`, `published`) VALUES ('".$aa1."','".$aa2."', '".$aa3."', '".$aa4."') ON DUPLICATE KEY UPDATE `id_product` = '".$aa1."', `date` = '".$aa2."', `available` = '".$aa3."', `published` = '".$aa4."'");
}
The problem is that this multiples the record in DB2 so I am now in millions!!!
Its set up as cron job on 1h basis.
What I need is ether it checks what is existing and don't touch it or if need on update or insert.
The other solution would be to delete the whole table in DB2 then to insert a fresh one from DB1
You can simplify your query like so:
INSERT INTO tbl2 (column1, column2)
SELECT column1, column2 FROM tbl1
ON DUPLICATE ...
See the documentation
You are looking for MySQL's proprietary REPLACE command. It has the same syntax as a regular INSERT, but it checks for duplicate primary key before inserting, and if it is found it will do an UPDATE instead:
REPLACE works exactly like INSERT, except that if an old row in the
table has the same value as a new row for a PRIMARY KEY or a UNIQUE
index, the old row is deleted before the new row is inserted.
Of course you will have to define a unique PK/index on your table that allows this functionality to work.
here is an update!
I solved the problem :)
Thanks s to Niels because he made me rethink my strategy so the solution was simple.
In the DB1 and DB2 there is and ID filed
A added
$aa5=$rowi['id'];
so that made ON DUPLICATE KEY UPDATE work correctly!
foreach($id_product_array AS $id_product) {
$resultf = mysql_query("SELECT * FROM db1_available_product WHERE id_product='".$id_product."'");
while($rowi = mysql_fetch_array($resultf)) {
$aa5=$rowi['id'];
$aa1=$rowi['id_product'];
$aa2=$rowi['date'];
$aa3=$rowi['available'];
$aa4=$rowi['published'];
mysql_query("INSERT INTO aa_bb.db2_available_product (`id`,`id_product`, `date`, `available`, `published`) VALUES ('".$aa5."','".$aa1."','".$aa2."', '".$aa3."', '".$aa4."') ON DUPLICATE KEY UPDATE `id` = '".$aa5."',`id_product` = '".$aa1."', `date` = '".$aa2."', `available` = '".$aa3."', `published` = '".$aa4."'");
}
and it seams that it is working OK!
:)

MySQL update from select and further select and updates

Currently trying to find a way to do the following inside some form of loop (preferably without a performance hit on database).
I have 3 tables user_hours, user_calendar and hours_statistics. I need to first do:
SELECT user_calendar.date_start,
user_calendar.opportunity_id,
user_hours.user_id,
user_hours.agreed_hours,
user_hours.completed_hours,
user_hours.hours_committed
FROM user_calendar
JOIN user_hours
ON user_calendar.user_calendar_id = user_hours.user_calendar_id
WHERE user_calendar.date_start = CURRENT_DATE()
AND user_hours.completed_hours IS NULL
AND user_hours.hours_committed = 'accepted'
This query could return like the following:
http://i.imgur.com/5cJ5v.png
So for each opportunity_id and user_id returned i'd like to then do:
UPDATE user_hours
SET completed_hours = agreed_hours,
hours_committed = 'completed'
WHERE opportunity_id = {opportunity_id}
AND user_id = {user_id}
AND hours_committed = 'accepted'
AND completed_hours IS NULL
Note that {opportunity_id} and {user_id} would need to be looped at this point (see screenshot) because we need to go through each user on each opportunity.
Then for each updated record i'd need to then get the total hours like:
// Get hours they have done to send to statistics data table
SELECT sum(completed_hours) FROM user_hours WHERE user_id = {user_id} AND opportunity_id = {opportunity_id} 
// Get the completed hours total somehow as a variable
$completed_hours = (from result above)
// Commit stats
UPDATE hours_statistics SET completed_hours = (completed_hours+$completed_hours)
WHERE user_id = {user_id} AND opportunity_id =  {opportunity_id} 
Could anyone help write this as a procedure or a trigger of some kind or help me in the right direction to get a starting point for looping over this stuff? Manually the querying works, just need to be looped / automatic for a stats update to run.
You can create a trigger to update hours_statistics whenever user_hours is updated (you may also want to add similar triggers for INSERT and DELETE operations, depending on your application logic).
Assuming that a UNIQUE key has been defined on hours_statistics.(user_id, opportunity_id) one can use INSERT ... ON DUPLICATE KEY UPDATE within the trigger:
CREATE TRIGGER foo AFTER UPDATE ON user_hours FOR EACH ROW
INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES
(OLD.user_id, OLD.opportunity_id, -OLD.completed_hours),
(NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)
ON DUPLICATE KEY UPDATE
completed_hours = completed_hours + VALUES(completed_hours);
Then you can use a single UPDATE statement (using the multiple-table syntax to join user_hours with user_calendar) to perform all of the updates on user_hours in one go, which will cause the above trigger to update hours_statistics as desired:
UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET user_hours.completed_hours = agreed_hours,
user_hours.hours_committed = 'completed'
WHERE user_hours.hours_committed = 'accepted'
AND user_hours.completed_hours IS NULL
AND user_calendar.date_start = CURRENT_DATE();

Categories