SQL Server 2008 trigger update when specific column changes - sql-server-2008

Other solutions got me this far, but ultimately things are not working for me.
I have a column in tbl_activity named abstract. When tbl_activity.abstract changes, I want to set tbl_activity.flag = 0.
My 2 versions of the trigger will set flag = 0, but then I cannot set flag back to 1, because changing that flag causes it to trigger, and it keeps setting the flag = 0. I've tried comparing old to new values, deleted to inserted values, and tried INSTEAD OF INSERT.
Can someone please examine this code and tell me what I'm missing?
ALTER TRIGGER [dbo].[AbstractChange] --trigger name
ON [dbo].[cpy_activity] --table using the trigger
INSTEAD OF UPDATE, DELETE
AS
UPDATE a
SET a.flag = 0
FROM tbl_activity a
INNER JOIN INSERTED i ON a.activityid = i.activityid
INNER JOIN DELETED d ON d.activityid = i.activityid
WHERE d.abstract NOT LIKE i.abstract
This results in "Command[s] completed successfully" - but when a column other than abstract changes, the trigger always sets flag = 0. Ideas?

Not sure what the datatype of abstract is - but I'm kinda guessing that the cause of your troubles is using the NOT LIKE operator in your trigger - try this instead:
ALTER TRIGGER [dbo].[AbstractChange] --trigger name
ON [dbo].[cpy_activity] --table using the trigger
INSTEAD OF UPDATE, DELETE
AS
UPDATE a
SET a.flag = 0
FROM tbl_activity a
INNER JOIN INSERTED i ON a.activityid = i.activityid
INNER JOIN DELETED d ON d.activityid = i.activityid
WHERE d.abstract <> i.abstract -- use the usual *not equal* operator <> here
Does that change anything?
Also: why is the trigger on cpy_activity, but inside the trigger, you're using tbl_activity - seems a bit odd, really .....

since the code i posted to ask my question, contained the erroneous use of INSTEAD OF - my "answer" at this point is that i changed my tbl_activity.abstract field from type Text to type Varchar(MAX) not null. One of the original problems was that the SQL trigger would not allow use of a text field. I will post that question properly on another post. Meanwhile, this code works, in the context where the "abstract" field is type varchar:
ALTER TRIGGER [dbo].[AbstractChange] --trigger name
ON [dbo].[tbl_activity] --table using the trigger
AFTER INSERT, UPDATE
AS UPDATE a
set a.flag = 0 --target action when above table is changed
FROM tbl_activity a
INNER JOIN INSERTED i ON a.activityid = i.activityid
INNER JOIN DELETED d ON d.activityid = i.activityid
WHERE d.abstract <> i.abstract

Related

MySQL Stored Procedure update using a Join and CASE..ELSE syntax

This is my first time creating a MySQL stored procedure and am stuck on getting the UPDATE piece to work correctly. The proc is performing an inner join, looking for matches on a domain name field. If there is a match, a column named inbound is getting updated with a value of 0. If there is not a match on the join, then I need inbound set to a value of 1.
When I run this, I am able to get the matches tagged with a 0, but the non-matches are not getting updated with a 1. I thought how I have the 'ELSE' part set up would take care of this- can anyone tell if I am missing something with the syntax?
CREATE PROCEDURE `sp_InboungTagging`()
BEGIN
update `tableA` a
inner join `TableD` d
on a.senderDomain = d.domainName
set inbound = CASE
when a.senderDomain = d.domainName then 0
ELSE 1
END
WHERE inbound is null;
END;|
DELIMITER ;
Thanks,
Ron
EDIT-
Thanks for your reply. I am looking for exact matches on a varchar field that has domain names in it- the master list of domains is in table D. If the record in TableA has a match in TableD, I want to tag that recored with a 0. If there is no match in TableD, then I would like to tag it with a 1. Let me know if that clears things up- thanks
Your JOIN condition is the same as your CASE condition. If you JOIN your two tables on:
a.senderDomain = d.domainName
Then there will be no values in the result set for which
a.senderDomain != d.domainName
so the ELSE clause of your CASE statement never fires.
Without knowing more about what you mean by "matches" and "non-matches," I can't really suggest a correction.

Trying to update table with values from second table MySQL results in unending "running query"

I'm trying to replace null values in one table with values from a second table, based on matches from other columns in both tables. While the code does not result in error, it does not stop running, producing an unending "running query" signal. code is here
UPDATE pl_building b
INNER JOIN pl_grt t
ON b.INST = t.inst
SET b.Utuition=t.tuition
WHERE b.UtUITION = 0;
You should not update on join tables.
I am not sure what field you want to update, but your SQL should look like this:
UPDATE pl_building b
SET b.Utuition= (select t.tuition from pl_grt t ON b.INST = t.inst)
WHERE b.UtUITION = 0;
Make sure :
1) You have an index on t.inst table column and maybe also on b.UtUITION
2) Relationship between b.INST = t.inst is unique. Never returns more than 1 row.

Updating table using JOIN not working correctly

I'm doing something like this:
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
SET b.`msa` = a.`msa`;
This executes just fine, but affects no rows. msa is set to NULL for all rows as if it wasn't changed at all. zip_code and msa are the same data types and length and definitely have overlapping zip_code. Any idea why this won't update?
EDIT: Update...I tried with a different column name and it ran as well, said that a set of my rows were affected, but none actually changed.
EDIT2: If I do this, then my msa column shows NULL for every row. Why wouldn't this value be here for a simple join?
SELECT * FROM `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
Something like the below should work.
UPDATE `widget_list`
SET `msa` = (SELECT `msa` FROM `geography` b
JOIN `widget_list` a
ON `a`.`zip_code` = `b`.`zip_code`
);
Able to reproduce using this fiddle
However by changing the order on the set function it works... as in this fiddle
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
SET a.`msa`=b.`msa` ;
and again that it should work.. implying it's a setup issue in your enviroment, or we're missing something (trigger perhaps?)
Working Fiddle Note however when mopre than one msa exists per zipcode A, X in my example for zip 123... the system simply picks one and uses it to update. X is lost in my example... are you sure that's not what's happening to you? (it's why I want to see sample data to see if it's a data issue vs syntax vs logic)
updated:
fiddle So if your source table has null values in the zipcodes you'll get null values in the destination table...
so what happens if we add....
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
and b.msa is not null
SET a.`msa`=b.`msa` ;
and fiddle showing excluded nulls
Use from to do join.
UPDATE widget_list
SET b.msa = a.msa
FROM widget_list a JOIN geography b ON b.zip_code = a.zip_code

How to set a column value equal to the value in another table?

I am trying to figure out how to update a row in one table, setting a column value equal to a value in a different table. Here's an example:
movies:
movie_id | movie_price
movies_attended:
attended_id | attended_movie_id | attended_movie_price
Now, this is kind of a stupid example, but supposed that for some reason there is a row in movies_attended that does not have the correct attended_movies_price in it and so it needs to be updated.
How should a query be written to update the movies_attended table, setting movies_attended.attended_movie_price = movies.movie_price?
I tried something similar to the following, but it did not work:
update movies_attended, movies
set movies_attended.attended_movie_price = movies.movie_price
where movies_attended.attended_movie_id = movies.movie_id
AND attended_id = [the id of the row we want to update]
When you say "it did not work", do you mean that it reported 0 rows updated, or did the statement cause the database raise an exception?
Your example statement appears to be of the form:
UPDATE movies_attended a
JOIN movies m
ON a.attended_movie_id = m.movie_id
SET a.attended_movie_price = m.movie_price
WHERE a.attended_id = ?
(We typically prefer the JOIN ... ON ... style syntax to the comma join operator and the join predicates in the WHERE clause.)
I have no explanation as to why this statement would "not work".
It's possible this would report 0 rows affected, if no rows satisfy the predicates. It would also report 0 rows affected if the rows that would be changed do not require any changes... that is, the existing value in attended_movie_price already matches the value being assigned to it.
Normally, before running an update statement like that, I write it as a SELECT first, and see what values are returned...
By replacing the UPDATE keyword with SELECT ... FROM, and removing the SET clause:
SELECT m.movie_price AS new_val
, a.attended_movie_price AS old_val
, a.attended_id
FROM UPDATE movies_attended a
JOIN movies m
ON a.attended_movie_id = m.movie_id
WHERE a.attended_id = ?
This is actually a bad database design. You don't need movie price in two tables.
But, if you just need this, it goes something along this:
UPDATE movies_attended
INNER JOIN
movies
ON movies_attended.attended_movie_id = movies.movie_id
SET movies_attended.attended_movie_price = movie.movie_price

MySQL Update a column depending on multi tables

I have a question regarding updating a MySQL database.
I have three tables: Match, Submission and SubmissionVersion. A SubmissionVersion can be set as 'Favorite'. But I can't just query UPDATE SubmissionVersion SET IsFavorite = 1 WHERE ID = $ID because of the relation to a Submission and than the Match. My question is how can I update a SubmissionVersion column with a MySQL Query with two joins? I've tried this query but I can't get it to work.
UPDATE
SubmissionVersion
JOIN
Submission
ON
Submission.ID, SubmissionVersion.SubmissionID
JOIN
Match
ON
Match.ID ON Submission.MatchID
SET
SubmissionVersion.IsFavorite = ".$Index."
WHERE
SubmissionVersion.ID = ".$ID."
AND
Match.ID = ".$MatchID
UPDATE SubmissionVersion sv
SET sv.IsFavorite = ".$Index."
WHERE sv.ID = ".$ID."
AND sv.ID IN (
SELECT s.ID
FROM Submission s
WHERE s.MatchID = ".$MatchID'")
If I understand your statement correctly, that should work.
I eliminated the Match table completely since you're just checking the value against a column in Submission.
Let's start with saying that MATCH is MySQL's reserved word, so needs to be put into backticks.
http://dev.mysql.com/doc/refman/5.1/en/reserved-words.html