问题
So I'm using the forum software Xenforo and I need help with a SQL query which will be executed periodically. The forum will have approximately 300-500 active users. So nothing too big.
The goal:
All users xf_users
need to be subscribed to node_id 71
except users which are part of certain user_group_id
.
Now users can unsubscribe from the forum or change the notify_on
and send_alert
& send_email
fields. I do not want that. So if users 'unsubscribe' they need to be added again.
The only accepted change is that notify_on
may also be "message".
Summarized:
If the user is not on the table with
node_id 71
, then insert the users intoxf_forum_watch
with thenode_id 71
,notify_on
is set to "thread" andsend_alert
&send_email
are set to "1".If the line with the
user_id
andnode_id 71
exists, updatesend_alert
andsend_email
to "1" if one of them is "0". Ifnotify_on
is blank: update to "thread".
What I got so far:
My thought #1 was a trigger. Thing is, i have never written a trigger and don't know how to solve my issue with it.
Thought #2 was to write an "Event" in phpMyAdmin which runs a query periodically.
I got the code working for inserting all the right users into the list once but I'm having issues with keeping the list updated.
I have tried using ON DUPLICATE KEY UPDATE
... but I didn't get it to work like intended.
My quick&dirty solution would be to delete all lines of node_id 71
and re-add all with the query below, but this wouldn't allow users to select notify_on
"message". Also
Help? ♥
The table:
Screenshot of the table
(!! the table will also include lines which are a different node_id
. These must remain untouched !!)
The code:
insert into xf_forum_watch
select user_id,
"71" as node_id,
"thread" as notify_on,
"1" as send_alert,
"1" as send_email
from xf_user
where user_group_id NOT IN (1, 18, 40);
This will add the correct users to the list (see screenshot). However, it will throw an error if the user is already subscribed.
I hope that I didn't leave out any details. If there are still questions, please let me know.
I appreciate all kinds of help.
PS: I hope I didn't ruin the formatting. I am not used to posting here.
edit: Thanks to @GMB for their solution.
I have a follow-up question. I want to put the working query into a stored procedure but it gives me an error:
DELIMITER $$
CREATE PROCEDURE forceSubscribeToNode(
IN node_id_var INT
)
BEGIN
insert into xf_forum_watch
(user_id, node_id, notify_on, send_alert, send_email)
select user_id,
node_id_var as node_id,
"thread" as notify_on,
1 as send_alert,
1 as send_email
from xf_user
where user_group_id NOT IN (1, 18, 40)
on duplicate key update
send_alert = 1,
send_email = 1,
notify_on = case when notify_on is null or notify_on = '' then 'thread' else notify_on end
END $$
DELIMITER ;
Error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 18
(Line 18 being "send_email = 1,")
What am I doing wrong?
回答1:
You can just add a on duplicate key
to your query:
insert into xf_forum_watch
(user_id, node_id, notify_on, send_alert, send_email)
select user_id,
71 as node_id,
'thread' as on notify_on,
1 as send_alert,
1 as send_email
from xf_user
where user_group_id NOT IN (1, 18, 40)
on duplicate key update
send_alert = 1,
send_email = 1,
notify_on = 'thread'
This assumes that you have the proper unique of primary key set up so that duplicates are properly identified.
If you want conditional logic in the on duplicate key
clause, that’s also possible:
on duplicate key update
send_alert = case when send_alert = 0 then 1 else send_alert end,
send_email = case when send_email = 0 then 1 else send_email end,
notify_on = case when notify_on is null or notify_on = '' then 'thread' else notify_on end
来源:https://stackoverflow.com/questions/63345517/mysql-query-problems-with-with-duplicates-on-insert-into