I have this trigger
DELIMITER ;
DELIMITER $$
CREATE TRIGGER when_auction_ends
AFTER UPDATE ON Auctions
FOR EACH ROW
BEGIN
SELECT A.vin, A.status, A.winner, A.minprice, B.amount, B.buyer INTO #vin, #stat, #winner, #minprice, #amount, #buyer
FROM Auctions A, Bids B WHERE A.status = 'Inactive' AND A.winner = null AND A.vin = B.vin AND B.amount = (SELECT MAX(amount) FROM Bids B WHERE B.vin = A.vin AS
IF #amount < #minprice THEN
UPDATE Auctions
SET A.winner = 'NONE'
WHERE A.vin = B.vin;
ELSEIF #amount >= #minprice THEN
UPDATE Auctions
SET A.winner = B.buyer
WHERE A.vin = B.vin;
END IF ;
END$$
DELIMITER ;
But when it activates, the values are not updated. I am thinking that its because mysql does not know what A.winner is in "SET A.winner". I tried looking online on how to use OLD and NEW but did not have any luck.
Related
I have a stored procedure with 1 parameter but linked to 3 tables, I want to display all of the table with one parameter with this query
CREATE DEFINER=`brambang`#`%` PROCEDURE `Read_discount_campaign`(IN Insert_ID INT(10)
)
proc:
BEGIN
DECLARE is_insert_id INT(10);
DECLARE param_1_message TEXT;
SET #is_insert_id = Insert_ID;
SELECT CONVERT( CONCAT('Maaf, ID discount_campaign tidak bisa \'0\'') USING UTF8) INTO param_1_message;
IF (Insert_ID = 0) THEN
SELECT param_1_message AS message;
LEAVE proc;
END IF;
IF (Insert_ID != 0) THEN
SELECT * FROM discount_campaigns where
id = #is_insert_id;
END IF;
IF (Insert_ID != 0) THEN
SELECT * FROM discount_campaign_advanced where
discount_campaign_id = #is_insert_id;
END IF;
IF (Insert_ID != 0) THEN
SELECT dcp.discount_campaign_id, CASE WHEN dcp.active = 0
THEN dcp.product_id ELSE pc.category_id END as discount_campaign_product
FROM discount_campaign_product dcp JOIN product_categories pc
ON dcp.product_id = pc.product_id
WHERE dcp.discount_campaign_id = Insert_ID;
END IF;
END
After I run this, the output was only from this query (last IF logic)
IF (Insert_ID != 0) THEN
SELECT dcp.discount_campaign_id, CASE WHEN dcp.active = 0
THEN dcp.product_id ELSE pc.category_id END as discount_campaign_product
FROM discount_campaign_product dcp JOIN product_categories pc
ON dcp.product_id = pc.product_id
WHERE dcp.discount_campaign_id = Insert_ID;
END IF;
Instead what I want is it displays all of the logic not only the last one, how to combine all of this logic so the output was from all of the logic, not only from the last logic, is it use cross join?
CREATE TRIGGER input_verification AFTER INSERT ON InputHistory
FOR EACH ROW
WHEN NO EXISTS (SELECT * FROM InputHistory JOIN Intput on InputHistory.inputId = Input.inputId WHERE InputHistory.inputId = NEW.inputId AND InputHistory.inputHistoryOrderNumber=Input.inputOrderNumber AND InputHistory.inputHistoryStatus >= 300)
BEGIN
DECLARE configId INTEGER;
SELECT Input.inputConfigurationId INTO configId FROM Input JOIN InputHistory ON Input.inputId = InputHistory.inputId WHERE NEW.inputId=Input.inputId;
UPDATE Configuration SET configurationReady = true WHERE configurationId= configId;
END
I have an AFTER INSERT-trigger that looks like this.
BEGIN
SET #newcompany = NEW.company_id;
IF NEW.company_id is not null THEN
SET #my_result = (SELECT count(*) FROM wp_wysija_user u
LEFT JOIN wp_pods_company c ON c.id = u.company_id
LEFT JOIN wp_podsrel rel ON c.id = rel.item_id
WHERE rel.field_id=3384 AND rel.related_item_id=5 AND u.company_id = #newcompany);
INSERT INTO wp_wysija_user_list(list_id, user_id, sub_date)
VALUES (5, NEW.user_id, UNIX_TIMESTAMP());
IF #my_result > 0 THEN
INSERT INTO wp_wysija_user_list(list_id, user_id, sub_date)
VALUES (7, NEW.user_id, UNIX_TIMESTAMP());
END IF;
END IF;
END
My problem is that #my_result is always 0. If I run the query outside the trigger I get the right count. At first I thought that the variable #newcompany didnĀ“t get a value. But I have checked that.
I need help here!
Don't understand why you use LEFT joins????
BEGIN
SET #newcompany = NEW.company_id;
IF NEW.company_id is not null THEN
SET #my_result = (SELECT count(*) FROM wp_wysija_user u
LEFT JOIN wp_pods_company c ON c.id = u.company_id
LEFT JOIN wp_podsrel rel ON c.id = rel.item_id and rel.field_id=3384 AND
rel.related_item_id=5
WHERE u.company_id = #newcompany);
INSERT INTO wp_wysija_user_list(list_id, user_id, sub_date)
VALUES (5, NEW.user_id, UNIX_TIMESTAMP());
IF #my_result > 0 THEN
INSERT INTO wp_wysija_user_list(list_id, user_id, sub_date)
VALUES (7, NEW.user_id, UNIX_TIMESTAMP());
END IF;
END IF;
END
Running into an error when trying to crate a stored procedure in MySQL (5.1).
Whenever I try and run this SQL script, I am presented with:
Error 1064 (42000) At line 3: You have an error in your SQL syntax.
Near 'DECLARE checkExists INT; SET checkExists = 0; SELECT count(*) INTO c' at line 29
From what I understand, declaring a variable this way should be acceptable.
I have included the SQL script below.
DELIMITER //
CREATE PROCEDURE add_movie(
IN movieTitle VARCHAR(100),
IN movieYear INT,
IN movieDirector VARCHAR(100),
IN movieBannerURL VARCHAR(100),
IN movieTrailerURL VARCHAR(100),
IN starFirstName VARCHAR(50),
IN starLastName VARCHAR(50),
IN starDateOfBirth DATE,
IN starPhotoURL VARCHAR(200),
IN genreName VARCHAR(32),
OUT movieAdded INT,
OUT starAdded INT,
OUT genreAdded INT,
OUT movieStarLinkAdded INT,
OUT movieGenreLinkAdded INT)
LANGUAGE SQL
NOT DETERMINISTIC
SQL SECURITY INVOKER
COMMENT 'Adds Movie, Star, Genre and respective links to DB if they do not exist'
BEGIN
SET movieAdded = 0;
SET starAdded = 0;
SET genreAdded = 0;
SET movieStarLinkAdded = 0;
SET movieGenreLinkAdded = 0;
DECLARE checkExists INT;
SET checkExists = 0;
SELECT count(*) INTO checkExists FROM movies m WHERE m.title = movieTitle;
IF(checkExists > 0) THEN
INSERT INTO movies(title, year, director, banner_url, trailer_url)
VALUES (movieTitle, movieYear, movieDirector, movieBannerURL, movieTrailerURL);
SET movieAdded = 1;
END IF;
SET checkExists = 0;
SELECT count(*) INTO checkExists FROM stars s WHERE s.first_name = starFirstName AND s.last_name = starLastName;
IF(checkExists > 0) THEN
INSERT INTO stars(first_name, last_name, dob, photo_url)
VALUES (starFirstName, starLastName, starDateOfBirth, starPhotoURL);
SET starAdded = 1;
END IF;
SET checkExists = 0;
SELECT count(*) INTO checkExists FROM genres g WHERE g.name = genreName;
IF(checkExists > 0) THEN
INSERT INTO genres(name)
VALUES (genreName);
SET genreAdded = 1;
END IF;
SET checkExists = 0;
SELECT count(*) INTO checkExists FROM stars_in_movies sm, stars s, movies m
WHERE m.title = movieTitle AND s.first_name = starFirstName
AND s.last_name = starLastName AND sm.star_id = s.id AND sm.movie_id = m.id;
IF(checkExists > 0) THEN
INSERT INTO stars_in_movies(star_id, movie_id)
VALUES(
SELECT s.id, m.id FROM stars s, movies m WHERE s.first_name = starFirstName
AND s.last_name = starLastName AND m.title = movieTitle);
SET movieStarLinkAdded = 1;
END IF;
SET checkExists = 0;
SELECT count(*) INTO checkExists FROM genres_in_movies gm, genres g, movies m
WHERE m.title = movieTitle AND genre.name = genreName
AND gm.movie_id = m.id AND gm.genre_id = g.id;
IF(checkExists > 0) THEN
INSERT INTO genres_in_movies(genre_id, movie_id)
VALUES(
SELECT g.id, m.id FROM genres g, movies m
WHERE g.name = genreName AND m.title = movieTitle);
SET movieGenreLinkAdded = 1;
END IF;
END //
DELIMITER ;
If someone could help me understand what I am doing incorrectly here, I would greatly appreciate it. Thank you.
Move all DECLARE statements to the start of a BEGIN .. END block, next to BEGIN.
See documentation: https://dev.mysql.com/doc/refman/5.6/en/declare.html
DECLARE is permitted only inside a BEGIN ... END compound statement and must be at its start, before any other statements.
So I have a routine that does (pseudo-code):
$rows = SELECT DISTINCT a, b FROM t1;
foreach($rows as $row) {
SET #i = 0;
UPDATE t1 SET c_index = #i := (#i+1)
WHERE a = $row[a] and b = $row[b] ORDER BY c DESC;
}
The point is to number a subset of rows by the way they are sorted. Works fine, but this is update runs thousands of times so is pretty slow. To speed it up I want to put it in a stored procedure.
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE vA, vB, i INT;
DECLARE cur1 CURSOR FOR
SELECT DISTINCT a, b
FROM t1 WHERE ...;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
WHILE done = 0 DO
FETCH cur1 INTO vA, vB;
IF done = 0 THEN
SET i=0;
UPDATE t1
SET c_index = i:= (i+1)
WHERE a = vA AND b = vB
ORDER BY c DESC;
END IF;
END WHILE;
CLOSE cur1;
END
However, when creating the above procedure MySQL says there is a syntax error at "i := ...". If I use a session variable for 'i' it works (#i). Using a session variable in a stored procedure is not very elegant. How can the above stored procedure be fixed without using a session variable for 'i'?
UPDATED: Since MySQL cursors are not updatable (read-only) there is no much sense of using one in your case. Almost everything you can possibly think of can be expressed just by pure UPDATE statement(s).
If (a, b, c) are unique you can do it this way
UPDATE table1 t JOIN
(
SELECT a, b, c,
(
SELECT 1 + COUNT(*)
FROM table1
WHERE a = t.a
AND b = t.b
AND c > t.c
) rnum
FROM table1 t
) s
ON t.a = s.a
AND t.b = s.b
AND t.c = s.c
SET t.c_index = s.rnum
Here is SQLFiddle demo
or if you happen to have some sort of id (e.g. auto_increment column) then
UPDATE table1 t JOIN
(
SELECT id,
(
SELECT 1 + COUNT(*)
FROM table1
WHERE a = t.a
AND b = t.b
AND c > t.c
) rnum
FROM table1 t
) s
ON t.id = s.id
SET t.c_index = s.rnum
Here is SQLFiddle demo