I have created a procedure and ran it, but it is showing some syntax probem, can you help me?
My procedure is as:
**DELIMITER $$
CREATE PROCEDURE TestAdd(
in mODE varchar(10),
in Id int,
in AttName varchar(10),
in AttValues Varchar(10)
)
IF EXISTS (SELECT * FROM AttTable WHERE id=Id) THEN
SET Mode='Modify'
ELSE
SET Mode='Add'
Start Transaction
BEGIN
IF (mODE='Add') THEN
insert into atttable values (Id, AttName, AttValue);
ELSE (if Mode='Modify') then
update AttTable set AttName=AttName, AttValue= AttValue where Id=Id;
END IF
END
$$
Delimiter ;**
You need a BEGIN right after the parameter list at the beginning, and a matching END at the end of the procedure:
create procedure TestAdd(blah...)
BEGIN
...
END$$
Your first IF call is missing both THEN and END IF:
if exists ( select * from AttTable where id=Id) THEN
set...
ELSE
set...
END IF
Each of the statements needs to be terminated with a ;
set Mode='Modify';
set Mode='Add';
Start Transaction;
Related
I first made a join between two other views to get a third view called AUX that is the one inside the procedure,now im wondering if the use of three temporary tables inside recipe is a better way to do it.
DROP PROCEDURE IF EXISTS recipe;
DELIMITER $$
CREATE PROCEDURE recipe(pIDrecipe INT, OUT pmessage VARCHAR(255))
SALIR:BEGIN
IF pIDrecipe IS NULL THEN
SET pmessage="wrong input" ;
LEAVE SALIR;
ELSEIF NOT EXISTS(SELECT pIDrecipe FROM Recipes WHERE IDrecipe = pIDrecipe) THEN
SET pmessage="not exists";
LEAVE SALIR;
ELSE
START TRANSACTION;
SELECT Name,ingredients,steps
FROM AUX WHERE IDrecipe = pIDrecipe;
SET pmessage="success" ;
COMMIT;
END IF;
END $$
DELIMITER ;
DELIMITER $$
USE `skilltest`$$
CREATE PROCEDURE Validate_User1($Username NVARCHAR(20), $_Password NVARCHAR(20))
BEGIN
DECLARE $UserId INT;DECLARE $LastLoginDate DATETIME;
IF EXISTS(SELECT (Username) FROM Users WHERE Username=$Username)
THEN
BEGIN
IF EXISTS(SELECT * FROM Users WHERE Username=$Username AND _Password=$_Password)
THEN
BEGIN
SELECT -1 -- UserValidate
END$$
ELSE
BEGIN
SELECT -2 -- Password Wrong
END$$
END$$
ELSE
BEGIN
SELECT -3 -- USERNAME DOES NOT EXIST
END$$
END$$
DELIMITER ;
Assuming this is mysql (there are elements in the code which suggest sql server) every statement must terminate with ; , a comment should be preceeded by # (not --), every if must have a matching end if; , begin..end blocks are not required in the if...endif blocks, only one else is allowed per if, every begin must have a matching end;
, only 1 end $$ is required. Although not required syntactically indenting your code makes it much more readable for us humans.
The following at least syntaxes
DROP PROCEDURE IF EXISTS Validate_User1;
DELIMITER $$
CREATE PROCEDURE Validate_User1($Username NVARCHAR(20), $_Password NVARCHAR(20))
BEGIN
DECLARE $UserId INT;DECLARE $LastLoginDate DATE;
IF EXISTS(SELECT Username FROM Users WHERE Username=$Username) THEN
IF EXISTS(SELECT * FROM Users WHERE Username=$Username AND _Password=$_Password) THEN
SELECT -1; #UserValidate
ELSE
SELECT -2; #Password Wrong
END IF;
ELSE
SELECT -3; #USERNAME DOES NOT EXIST
END IF;
END $$
DELIMITER ;
Here is my Trigger
DELIMITER $$
CREATE TRIGGER before_insert BEFORE INSERT ON SampleTable
FOR EACH ROW
BEGIN
IF NEW.flag =0 THEN
SET NEW.media = "../trigger/smile1.png";
ELSEIF NEW.flag = 1 THEN
SET NEW.media = "../trigger/smile2.png";
ELSEIF NEW.flag = 2 THEN
SET NEW.media = "../trigger/smile3.png";
END IF;
CALL Media (NEW.flag);
END$$
DELIMITER ;
The trigger was created successfully. And I called stored procedure from a trigger.
procedure
DELIMITER $$
CREATE PROCEDURE Media (a INT)
BEGIN
SELECT firstname, lastname, media FROM SampleTable WHERE flag = a;
END $$
DELIMITER ;
When I use insert query it shows the following error.
not allowed to return a result set from a trigger
I found select query is a reason for the error. But I don't know how to solve it.
Any Help...
I am trying to write a trigger that would simplify logging changes when a record is updated. I have a stored procedure that does an INSERT to a logging table called log_update and a trigger that does the job for 1 field:
DROP TRIGGER IF EXISTS `parents_update`;
DELIMITER $$
CREATE TRIGGER `parents_update` AFTER UPDATE ON `parents`
FOR EACH ROW
BEGIN
IF ( NEW.motherLastName != OLD.motherLastName ) THEN
CALL log_update( 'parent', NEW.id, 4, CONCAT( OLD.motherLastName, ' > ', NEW.motherLastName ) );
END IF;
END;
$$
DELIMITER ;
Is it a way to make this more generic like provide list of fields:
( 'motherFirstName', 'motherLastName', 'fatherFistName', .... )
and loop through this list with a parameter for the single IF statement?
Edit:
I come up with such loop:
DROP TRIGGER IF EXISTS `parents_update`;
DELIMITER $$
CREATE TRIGGER `parents_update` AFTER UPDATE ON `parents`
FOR EACH ROW
BEGIN
DECLARE _fieldName VARCHAR(25);
DECLARE done INT DEFAULT FALSE;
DECLARE fieldsCursor CURSOR FOR SELECT fieldName FROM log_fields WHERE tableName = 'parents';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN fieldsCursor;
the_loop : LOOP
FETCH fieldsCursor INTO _fieldName;
IF done THEN
LEAVE the_loop;
END IF;
-- _fieldName will contain values such 'motherLastName'
IF ( NEW ( _fieldName ) != OLD ( _fieldName ) ) THEN
CALL log_update( 'parent', NEW.id, 4, CONCAT( OLD ( _fieldName ), ' > ', NEW ( _fieldName ) ) );
END IF;
END LOOP the_loop;
CLOSE fieldCursor;
END;
$$
DELIMITER ;
where table log_fields will contain fields to check. Now I am facing the problem of how to access the NEW. or OLD. property if the field name is in a variable.
I would say you can use prepared statements to achieve it, but unfortunately it is not supported in triggers.
You can read more about it here: http://dev.mysql.com/doc/refman/5.1/en/stored-program-restrictions.html OR answer here: Alternative to using Prepared Statement in Trigger with MySQL
which mean you can't create dynamic SQL query in your trigger the same applied to NEW. or OLD. variables dinamic build, so the only way is create separate triggers for each table with listed all column names one by one
I have a MySQL table , look like this
t id lang title
1 7 en_UK my_title
1 7 kh_KH
I want write a trigger that update title to my_title with the same id is 7
Result
t id lang title
1 7 en_UK my_title
1 7 kh_KH my_title
From my understanding.
DELIMITER $$
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
IF (NEW.title IS NULL OR NEW.title= '') THEN
SET NEW.title= ??? ;
END IF;
END$$
DELIMITER ;
[UPDATE1]->not works (trigger not being created)
DELIMITER $$
DROP TRIGGER IF EXISTS `update_category_after_insert`
CREATE TRIGGER `update_category` AFTER INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
[UPDATE2]
DELIMITER $$
CREATE TRIGGER ``update_category_after_insert`` BEFORE INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
Finally , I found the good solution for my case
UPDATE categories c INNER JOIN categories c2 ON (
c.num_noeud = c2.num_noeud
) SET c.libelle_categorie = c2.`libelle_categorie`
Can you clarify?
Are you trying to pull the value from the title column in the 'en_UK' row that exists when you insert an new row with the same id that HAS the title column not entered?
okay
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
DECLARE loc_title VARCHAR(20);
IF (NEW.title IS NULL OR NEW.title= '') THEN
select title into loc_title from term where NEW.id = id and lang = 'en_UK';
SET NEW.title= loc_title;
END IF;
END
This should do the trick.
This was my trigger def:
CREATE DEFINER = CURRENT_USER TRIGGER `therinks`.`glreturndata_BEFORE_UPDATE` BEFORE UPDATE ON `glreturndata` FOR EACH ROW
BEGIN
DECLARE myVal VARCHAR(20);
if NEW.DESCRIPTION IS NULL or new.description = '' THEN
SELECT min(description) into myVal from glreturndata where category = NEW.category and new.idglreturndata <> idglreturndata;
Set NEW.DESCRIPTION = myval;
end if;
END
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.