i have the following code that is giving me a headache, i need to create this stored procedure for a database, however, i can save it nor implement it due to a Syntax error at 'AS'. I need to know what am i doing wrong?
Create PROCEDURE `insert_delete_update` (OUT
id int,
level varchar(225),
action varchar(20)
)
AS
BEGIN
SET NOCOUNT ON;
IF #Action = 'Insert'
BEGIN
insert into levels (id, level) values(#id, #level)
END
IF #Action = 'Select'
BEGIN
select * from levels
END
IF #Action = 'Update'
BEGIN
UPDATE levels SET
level = #level
WHERE id = #id
END
else IF #Action = 'Delete'
BEGIN
DELETE FROM levels WHERE id = #id
END
END
Right so i finally got my answer.
Here is the final code:
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_delete_update`()
BEGIN
Declare id int;
Declare level varchar(225);
Declare action varchar(20);
Set #Action = 'Insert';
BEGIN
insert into levels (id, level) values(#id, #level);
END;
SET #Action = 'Select';
BEGIN
select * from levels
END ;
SET #Action = 'Update';
BEGIN
UPDATE levels SET
level = #level
WHERE id = #id;
END;
SET #Action = 'Delete';
BEGIN
DELETE FROM levels WHERE id = #id;
END;
END;
END
Thx for all your help!
I have written stored procedure for you. You can use it and I hope it will resolve your problem. I have created from workbench only.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_delete_update`(OUT
id int,
level varchar(225),
action varchar(20))
BEGIN
if #action = 'Insert' THEN
insert into levels (id, level) values(#id, #level) ;
elseif #action = 'Select' THEN
select * from levels ;
elseif #action = 'Update' THEN
UPDATE levels SET
level = #level
WHERE id = #id;
elseif #action = 'Delete' THEN
DELETE FROM levels WHERE id = #id;
end if;
END$$
DELIMITER ;
Related
So basically I have a MySQL after insert trigger which should listen for insert operation, after a new row has been inserted in my monetaryTransactions table, the trigger should check whether the date of the new insert is smaller than the last date present in my other deposits table, and if that date is bigger (i.e newer), it should ALSO insert the record in the deposits table
This is the trigger itself ->
DELIMITER //
CREATE TRIGGER lv_deps_trigger
AFTER INSERT
ON MonetaryTransactions FOR EACH ROW
BEGIN
DECLARE ftdInt tinyint(1);
DECLARE agentName varchar(40);
DECLARE businessUnit varchar(40);
DECLARE parsedUnit varchar(40);
DECLARE depDate DATETIME;
DECLARE payment varchar(255);
IF (NEW.FirstTimeDeposit = 'false') THEN
SET ftdInt = 0;
ELSE
SET ftdInt = 1;
END IF;
SELECT FullName FROM users WHERE SystemUserId = NEW.MTTransactionOwner INTO agentName;
SELECT `Bu Name` FROM users WHERE SystemUserId = NEW.MTTransactionOwner INTO businessUnit;
SELECT ApprovedOn FROM deposits ORDER BY ApprovedOn desc LIMIT 1 INTO depDate;
IF (businessUnit LIKE '%dummy%') THEN
SET parsedUnit = 'dummy';
ELSE
SET parsedUnit = 'dummy';
END IF;
CALL processorFetcher(NEW.new_paymentprocessor, #AttrValue);
SELECT #AttrValue INTO payment;
IF (depDate < NEW.Lv_ApprovedOn ) THEN
IF (NEW.Lv_name IN('Deposit','Withdrawal')) THEN
INSERT INTO deposits(TPAccountID,Brand,AgentName,ApprovedOn,Amount,PaymentMethod,TransactionType,Department,FirstTimeDeposit) VALUES(NEW.TPAccountID, NEW.Department, agentName, NEW.Lv_ApprovedOn, NEW.Lv_Amount, payment, NEW.Lv_name, parsedUnit, ftdInt);
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Not a wd/dp';
END IF;
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Nothing to insert';
END IF;
END; //
DELIMITER ;
Basically, what it does right now is to check for the date, and only if that depDate < NEW.Lv_ApprovedOn condition returns true it will insert the record in both the deposits table and the monetarytransactions one. If the condition returns false, it will just trigger the else statement (nothing to insert) and it won't insert the record in the MonetaryTransactions.
This is indeed the logical behaviour I assume, however, I am unsure on how exactly I need to rework this so that IF the date is newer, it'll insert the record in both tables, if it's older, it will insert it only in the monetaryTransactions table.
I have attempted to just put an INSERT INTO monetarytransactions... in the ELSE condition but as expected it throws an error that I am not allowed to do that.
Any advice is welcome!
in Your case it would be more suitable to use BEFORE INSERT as it would let the INSERT query in the original table to proceed even if the "IF" statement is false, which is exactly Your case, and of course if it is getting in the IF statement it would INSERT into the original table and the trigger would do its work
DELIMITER //
CREATE TRIGGER lv_deps_trigger
BEFORE INSERT
ON lvr_MonetaryTransactions FOR EACH ROW
BEGIN
DECLARE ftdInt tinyint(1);
DECLARE agentName varchar(40);
DECLARE businessUnit varchar(40);
DECLARE parsedUnit varchar(40);
DECLARE depDate DATETIME;
DECLARE payment varchar(255);
IF (NEW.Lv_FirstTimeDeposit = 'false') THEN
SET ftdInt = 0;
ELSE
SET ftdInt = 1;
END IF;
SELECT FullName FROM lvr_users WHERE SystemUserId = NEW.Lv_MTTransactionOwner INTO agentName;
SELECT `Bu Name` FROM lvr_users WHERE SystemUserId = NEW.Lv_MTTransactionOwner INTO businessUnit;
SELECT ApprovedOn FROM dep0sits ORDER BY ApprovedOn desc LIMIT 1 INTO depDate;
IF (businessUnit LIKE '%Conversion%') THEN
SET parsedUnit = 'Conversion';
ELSE
SET parsedUnit = 'Retention';
END IF;
CALL processorFetcher(NEW.new_paymentprocessor, #AttrValue);
SELECT #AttrValue INTO payment;
IF (depDate < NEW.Lv_ApprovedOn ) THEN
IF (NEW.Lv_name IN('Deposit','Withdrawal')) THEN
INSERT INTO dep0sits(TPAccountID,Brand,AgentName,ApprovedOn,Amount,PaymentMethod,TransactionType,Department,FirstTimeDeposit) VALUES(NEW.TPAccountID, NEW.Department, agentName, NEW.Lv_ApprovedOn, NEW.Lv_Amount, payment, NEW.Lv_name, parsedUnit, ftdInt);
ELSE
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Not a wd/dp';
END IF;
ELSE
SET NEW.Lv_monetarytransactionId = NEW.Lv_monetarytransactionId;
SET NEW.CreatedOn = NEW.CreatedOn;
SET NEW.Lv_name = NEW.Lv_name;
SET NEW.lv_type = NEW.lv_type;
SET NEW.lv_accountid = NEW.lv_accountid;
SET NEW.Lv_Amount = NEW.Lv_Amount;
SET NEW.Lv_ApprovedOn = NEW.Lv_ApprovedOn;
SET NEW.Lv_FirstTimeDeposit = NEW.Lv_FirstTimeDeposit;
SET NEW.CurrencyName = NEW.CurrencyName;
SET NEW.Lv_internalcomment = NEW.Lv_internalcomment;
SET NEW.Lv_MTTransactionOwner = NEW.Lv_MTTransactionOwner;
SET NEW.lv_tpaccountid = NEW.lv_tpaccountid;
SET NEW.TPAccountID = NEW.TPAccountID;
SET NEW.Lv_TransactionApproved = NEW.Lv_TransactionApproved;
SET NEW.Lv_USDValue = NEW.Lv_USDValue;
SET NEW.new_paymentprocessor = NEW.new_paymentprocessor;
SET NEW.Department = NEW.Department;
END IF;
END; //
DELIMITER ;
I have this procedure which loops through article values, fetch tag1 and insert it into article_tag table:
DELIMITER $$
CREATE PROCEDURE dt1()
BEGIN
DECLARE maxid INT;
DECLARE x INT;
DECLARE t VARCHAR(30);
DECLARE ntag1 int;
SET maxid = (SELECT MAX(id) FROM `article`);
SET x = (SELECT MIN(id) FROM `article`) ;
WHILE x<= maxid DO
SET t = (SELECT tag1 from `article` WHERE id=x);
SET ntag1 = (SELECT count(*) from `article_tag` WHERE tag=t);
IF ntag1 = 0
THEN
INSERT INTO `article_tag` (tag, slug, frequency) VALUES (t, t, 1);
ELSE
UPDATE `article_tag` SET frequency = frequency + 1 WHERE tag=t;
END IF;
SET x = x + 1;
END WHILE;
END$$
This works fine when there are rows with id in the while loop, but when when there are some missing ids in between (like here)
I get
Query Error: Error: ER_BAD_NULL_ERROR: Column 'tag' cannot be null
I'm wondering what is the idiomatic way to deal with such missing rows?
You can use loop with cursor, so you will only loop through existing records and do not need to check for NULL.
Something like this:
DELIMITER \\
CREATE PROCEDURE dt1()
BEGIN
DECLARE t VARCHAR(30);
DECLARE done INT DEFAULT FALSE;
DECLARE cur1 CURSOR FOR SELECT tag FROM `article` ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
loop1: LOOP
FETCH cur1 INTO t;
IF done THEN
LEAVE loop1;
END IF;
SELECT COUNT(*) INTO #cnt from `article_tag` WHERE tag = t;
IF #cnt = 0 THEN
INSERT INTO `article_tag` (tag, slug, frequency) VALUES (t, t, 1);
ELSE
UPDATE `article_tag` SET frequency = frequency + 1 WHERE tag = t;
END IF;
END LOOP;
CLOSE cur1;
END
\\
DELIMITER ;
See manual for details:
https://dev.mysql.com/doc/refman/5.7/en/cursors.html
Sure, if possible I'd use INSERT ON DUPLICATE UPDATE as already mentioned.
I am creating Trigger into Mysql Workbanch , but not able to create the trigger.
Can Anyone Help me For This.
DELIMITER $$
create TRIGGER Insert_Test
After Delete ON Test
FOR EACH ROW
BEGIN
START TRANSACTION;
DECLARE v_ID INT;
DECLARE v_Error TINYINT;
DECLARE v_AgentID INT;
SELECT v_Error = 0;
v_ID=Old.id;
BEGIN
DELETE Test2 WHERE id = SELECT id FROM Test where id=v_ID;
Rollback;
SET v_Error = 1;
END
IF v_Error = 0;
THEN
COMMIT;
ELSEIF
v_Error = 1;
THEN
ROLLBACK;
END IF;
END
DELIMITER ;
Sql server Trigger
ALTER TRIGGER [dbo].[tr_DelRecordTypeID] ON [dbo].[luRecordType] FOR DELETE
AS
SET NOCOUNT ON
BEGIN TRANSACTION
DECLARE #ID INT, #GroupTypeID INT, #Error BIT, #Msg VARCHAR(500)
SELECT #Error = 0
SELECT #ID = RecordTypeID FROM deleted
SELECT #GroupTypeID = 30
IF EXISTS ( SELECT g.GroupID
FROM luGroup g,
[luGroupDetail] gd
WHERE g.[GroupID] = gd.[GroupID]
AND g.[GroupTypeID] = #GroupTypeID
AND gd.[MemberID] = #ID )
BEGIN
DELETE [agAgent] WHERE [AgentID] = (SELECT TOP 1 AgentID FROM agAgentPayType)
Rollback transaction
SET #Error = 1
END
IF #Error = 0
BEGIN
COMMIT TRANSACTION
END
ELSE
IF #Error = 1
BEGIN
ROLLBACK TRANSACTION
END
This trigger which i am trying to achieve into mysql workbanch, please check
I shall Be thankful,
Thanks
Aman
I am making a procedure that inserts a place ("Sted") and I would like to check if the inputs are NULL. However, whenever I try to add an if-statement at the start to surround my code (marked CRASH below), it gives me an error saying my syntax is not right at "DECLARE varStedskodeID INT;" which is the part after the IF-statement I'm trying to add.
To my eyes the syntax of my if-statement is the same inside the code, but only my soon-to-be-NULL-check if-statement crashes even with just a simple IF(TRUE) THEN.
Can anyone give me a hint of what causes this one if to crash?
DROP PROCEDURE IF EXISTS InsertSted;
DELIMITER $$
CREATE PROCEDURE InsertSted(
IN inputStedsnavn VARCHAR(255),
IN inputStedstype VARCHAR(255),
IN inputKommunenavn VARCHAR(255))
BEGIN
IF(TRUE) THEN <<------ CRASH
DECLARE varStedskodeID INT;
DECLARE varKommunenr INT;
IF(SELECT COUNT(StedkodeID) FROM stedstype WHERE Kodenavn = inputStedstype LIMIT 1) = 0 THEN
INSERT INTO stedstype VALUES(DEFAULT, inputStedstype);
END IF;
SET varStedskodeID = (SELECT StedkodeID FROM stedstype WHERE Kodenavn = inputStedstype LIMIT 1);
IF(SELECT COUNT(Kommunenr) FROM kommune WHERE Kommunenavn = inputKommunenavn LIMIT 1) = 1 THEN
SET varKommunenr = (SELECT Kommunenr FROM kommune WHERE Kommunenavn = inputKommunenavn LIMIT 1);
INSERT INTO sted VALUES(DEFAULT, inputStedsnavn, varStedskodeID, varKommunenr);
END IF;
END IF; <<------ CRASH
END$$
DELIMITER ;
DECLARE is permitted only inside a BEGIN ... END compound statement
and must be at its start, before any other statements.
http://dev.mysql.com/doc/refman/5.0/en/declare.html
MySQL follows strict rules for DECLARE. You have to DECLARE variables, tables, etc... at the beginning of Stored Procedure.
Change Stored Procedure like this
DECLARE varStedskodeID INT;
DECLARE varKommunenr INT;
IF(TRUE) THEN
IF(SELECT COUNT(StedkodeID) FROM stedstype WHERE Kodenavn = inputStedstype LIMIT 1) = 0 THEN
INSERT INTO stedstype VALUES(DEFAULT, inputStedstype);
END IF;
SET varStedskodeID = (SELECT StedkodeID FROM stedstype WHERE Kodenavn = inputStedstype LIMIT 1);
IF(SELECT COUNT(Kommunenr) FROM kommune WHERE Kommunenavn = inputKommunenavn LIMIT 1) = 1 THEN
SET varKommunenr = (SELECT Kommunenr FROM kommune WHERE Kommunenavn = inputKommunenavn LIMIT 1);
INSERT INTO sted VALUES(DEFAULT, inputStedsnavn, varStedskodeID, varKommunenr);
END IF;
END IF;
when the table user delete fail,why the next sql will be exceute.who can give me a full example for mysql procedure.i want to delete example.please help?
use test;
delimiter //
create procedure proc_name(in paramter int)
begin
declare t_error int default 0;
declare continue handler for sqlexception set t_error=1;
set autocommit = 0;
START TRANSACTION;
delete from `user` where id = paramter;
delete from `user_info` where uid = paramter;
if t_error=1 then
rollback;
else
commit;
end if;
end;
//
delimiter ;
Dinel, I would change a little bit of your logic to achieve what you are looking for:
use test;
delimiter //
create procedure proc_name(in paramter int)
begin
declare continue handler for sqlexception set t_error=1;
SET #t_error = 0;
START TRANSACTION;
delete from `user` where id = paramter;
SELECT #t_error := COUNT(*) from `user` where id = paramter;
if #t_error != 0 then
ROLLBACK;
else
DELETE FROM `user_info` WHERE uid = paramter;
COMMIT;
end if;
end;
//
delimiter ;
I didn't try the syntax, but it should work. ;-)