TRIGGER MYSQL NOT EXIST - mysql

I created this trigger:
CREATE TABLE `Invitations`
( `userId` varchar(255) NOT NULL, `name` varchar(255) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL, `userId_inv` varchar(255) NOT NULL,
PRIMARY KEY (`userId`,`userId_inv`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
IF ((new.userId,'001') NOT EXISTS (SELECT `userId`,`userId_inv` FROM `Invitations`
WHERE `userId`= new.userId AND `userId_inv` = '001' LIMIT 1))
THEN
INSERT INTO `Invitations`(`userId`, `name`,`status`,`userId_inv`)
values (new.userId, new.name,new.status,'001');
DELETE FROM `invitation_001` WHERE `status` = 'a';
END IF;
END;
It did not work. I had this error:
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 'EXISTS (SELECT userId,userId_inv FROM Invitations WHERE
userId= new.user' at line 1
So could you help me.
I resolved the problem with this trigger:
CREATE TRIGGER `Invitation_001_after_trig` AFTER INSERT ON `invitation_001`
FOR EACH ROW
BEGIN
INSERT INTO `Invitations` (`userId`, `name` ,`status` ,`userId_inv`) SELECT * FROM
invitation_001 iv WHERE
NOT EXISTS (SELECT 1 FROM `Invitations` ivs WHERE ivs.`userId` = iv.`userId` AND
ivs.`userId_inv` = iv.`userId_inv`) AND iv.`userId_inv`='001';END;
Now I've an other issue. I would like to execute a query from a Concat String in a trigger but until now I did not succeed so here is my code:
CREATE TRIGGER `InvitationS_after_trig` AFTER INSERT ON `Invitations`
FOR EACH ROW
BEGIN
if(new.status ='c' OR new.status ='r')
BEGIN
SET #query = CONCAT("INSERT INTO", Invetations.userId,"values(new.userId,new.name,new.status,new.userId_inv);");
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END IF;
END;
I resolved the syntax problem but I now have an other one:
Dynamic SQL is not allowed in stored function or trigger
I'm using MySQL version 5.1.69.
Finally I give up, I will resolve this problem using java Fonction

Related

Does the MySQL prepare syntax not support the update statement?

I used the DBeaver to connect MySql.
CREATE TABLE `test2` (
`id` varchar(100) DEFAULT NULL,
`code` varchar(100) DEFAULT NULL,
`age` int DEFAULT NULL,
`name` varchar(100) DEFAULT NULL
);
INSERT INTO mp.test2
(id, code, age, name)
VALUES('abc', 'cc', 0, 'mike');
I create a temp script in DBeaver
and try to execute the sql script :
PREPARE stmt from 'update test2 set age = 3';
EXECUTE stmt ;
DEALLOCATE PREPARE stmt;
I get error: Unknown prepared statement handler (stmt) given to EXECUTE
I want to know what's wrong with this sql. what's the correct sql to update data by using Prepare?

How do I create table if a reference record doesn't exist else insert?

I designed a system which received request with ResortId, DayId, SkierId, Time, LiftId.
I created a table called day_resort with ResortId, DayId, and a reference which equals the concatenation of ResortId and DayId. When I received a request with Reference (ResortId + DayId) exists in the day_resort. I will simply find the table with name = Reference and insert SkierId, Time, and LiftId there. On the contrary, if I don't find certain Reference in day_resort, I will create a table name after ResortId + DayId, and I will insert the record with ResortId, DayId, ResortId + DayId into day_resort, after that, I will go to the table name after ResortId + DayId and insert a record with SkierId, Time, and LiftId.
Here is the example I tried:
DELIMITER //
DROP PROCEDURE IF EXISTS createLogTable;
CREATE PROCEDURE createLogTable(tblName VARCHAR(255))
BEGIN
SET #tableName = tblName;
SET #sql := CASE
WHEN NOT EXISTS (SELECT * FROM day_resort WHERE Reference = #tableName) THEN
'INSERT INTO day_resort (ResortId, DayId, Reference) VALUES ("Marriot", "21", "Marriot21")';
ELSE
CONCAT('INSERT INTO `' , #tableName, '` (SkierId, TIme, LiftId) VALUES ("111", "222", "333")');
END;
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS #tableName (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
SkierId VARCHAR(255) NOT NULL
Time VARCHAR(255) NOT NULL,
LiftId VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
END //
I got an error of Error Code: 2014 Commands out of sync; you can't run this command now
Thanks for any help

error while calling stored procedure: You are using safe update

I am trying to call a stored procedure, but I am getting : Error Code: 1175 You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
Here is the table:
CREATE TABLE `SystemSetting` (
`SettingName` varchar(45) NOT NULL,
`SettingValue` varchar(45) NOT NULL,
`Deleted` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`SettingName`),
KEY `PK_SystemSetting` (`SettingName`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and the procedure:
DELIMITER $$
CREATE PROCEDURE `SystemSettingCommit` (IN p_SettingName varchar(45), IN p_SettingValue varchar(45), OUT p_Status varchar(55))
BEGIN
SET p_Status = '00000';
IF (p_SettingValue IS NULL) OR (RTRIM(LTRIM(p_SettingValue)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10016');
END IF;
IF (p_SettingName IS NULL) OR (RTRIM(LTRIM(p_SettingName)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10017');
END IF;
IF (p_Status = '00000') THEN
IF ((SELECT COUNT(`SettingName`) FROM `SystemSetting` WHERE (`SettingName` = p_SettingName)) > 0) THEN
UPDATE `SystemSetting` SET `SettingValue` = p_SettingValue WHERE (`SettingName` = p_SettingName);
ELSE
INSERT INTO `SystemSetting` (`SettingName`, `SettingValue`) VALUES (p_SettingName, p_SettingValue);
END IF;
END IF;
END$$
DELIMITER;
and this is how I call it:
CALL `SystemSettingCommit` ('Setting1', 'Value1', #Status);
Try this:
SET SQL_SAFE_UPDATES=0;
Or follow this in workbench:
Go to Edit --> Preferences
Click "SQL Queries" tab and uncheck "Safe Updates" check box
Query --> Reconnect to Server
Now execute your sql query

Mysql Prepared Statement with Constraint

I have a Table Structure as below
CREATE TABLE `eatables` (
`Sno` int(11) NOT NULL auto_increment,
`Name` varchar(255) collate latin1_general_ci default NULL,
PRIMARY KEY (`Sno`)
);
The Table contains Rows as below
insert into `eatables`(`Sno`,`Name`) values (1,'Apples');
insert into `eatables`(`Sno`,`Name`) values (2,'Oranges');
insert into `eatables`(`Sno`,`Name`) values (3,'Papaya');
insert into `eatables`(`Sno`,`Name`) values (4,'Jackfruit');
insert into `eatables`(`Sno`,`Name`) values (5,'Pineapple');
insert into `eatables`(`Sno`,`Name`) values (6,'Mango');
I created a Procedure to get the Count based on Name as Constraint
DROP PROCEDURE IF EXISTS proc_fruit_count;
CREATE PROCEDURE mp_user_preference(pFruitName VARCHAR(255))
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName;
SELECT #lngCount;
END
But my Procedure is returning Null every time I execute it.
You have to modify your stored procedure! You also need to use IN keyword:
CREATE PROCEDURE mp_user_preference(IN pFruitName VARCHAR(255))
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName;
SELECT #lngCount;
END
See http://www.mysqltutorial.org/stored-procedures-parameters.aspx
Edit:If you want to return lngCount you can modify the stored procedure as follow:
CREATE PROCEDURE mp_user_preference(IN pFruitName VARCHAR(255), OUT toReturn INT)
BEGIN
SELECT #lngCount = COUNT(Sno)
FROM eatables
WHERE Name = pFruitName
INTO toReturn;
END
You don't need a stored procedure here. You can solve this conveniently with a prepared statement.
prepare stmt from 'select count(*) from eatables where name = ?';
set #whatever = 'Mango';
execute stmt using #whatever; /* #whatever replaces the ? in the query above */
/* and if you don't need the prepared statement any more you do... */
deallocate prepare stmt;
Read more about prepared statements here.

Change auto increment starting number?

In MySQL, I have a table, and I want to set the auto_increment value to 5 instead of 1. Is this possible and what query statement does this?
You can use ALTER TABLE to change the auto_increment initial value:
ALTER TABLE tbl AUTO_INCREMENT = 5;
See the MySQL reference for more details.
Yes, you can use the ALTER TABLE t AUTO_INCREMENT = 42 statement. However, you need to be aware that this will cause the rebuilding of your entire table, at least with InnoDB and certain MySQL versions. If you have an already existing dataset with millions of rows, it could take a very long time to complete.
In my experience, it's better to do the following:
BEGIN WORK;
-- You may also need to add other mandatory columns and values
INSERT INTO t (id) VALUES (42);
ROLLBACK;
In this way, even if you're rolling back the transaction, MySQL will keep the auto-increment value, and the change will be applied instantly.
You can verify this by issuing a SHOW CREATE TABLE t statement. You should see:
> SHOW CREATE TABLE t \G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
...
) ENGINE=InnoDB AUTO_INCREMENT=43 ...
How to auto increment by one, starting at 10 in MySQL:
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'10', 'abc'
'11', 'def'
'12', 'xyz'
This auto increments the id column by one starting at 10.
Auto increment in MySQL by 5, starting at 10:
drop table foobar
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
SET ##auto_increment_increment=5;
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'11', 'abc'
'16', 'def'
'21', 'xyz'
This auto increments the id column by 5 each time, starting at 10.
You can also do it using phpmyadmin. Just select the table than go to actions. And change the Auto increment below table options. Don't forget to click on start
Procedure to auto fix AUTO_INCREMENT value of table
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(64))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(`id`), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END//
DELIMITER ;
CALL update_auto_increment('your_table_name')
If you need this procedure for variable fieldnames instead of id this might be helpful:
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(128), _fieldname VARCHAR(128))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(',_fieldname,'), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END //
DELIMITER ;
CALL update_auto_increment('your_table_name', 'autoincrement_fieldname');
just export the table with data ..
then copy its sql like
CREATE TABLE IF NOT EXISTS `employees` (
`emp_badgenumber` int(20) NOT NULL AUTO_INCREMENT,
`emp_fullname` varchar(100) NOT NULL,
`emp_father_name` varchar(30) NOT NULL,
`emp_mobile` varchar(20) DEFAULT NULL,
`emp_cnic` varchar(20) DEFAULT NULL,
`emp_gender` varchar(10) NOT NULL,
`emp_is_deleted` tinyint(4) DEFAULT '0',
`emp_registration_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`emp_overtime_allowed` tinyint(4) DEFAULT '1',
PRIMARY KEY (`emp_badgenumber`),
UNIQUE KEY `bagdenumber` (`emp_badgenumber`),
KEY `emp_badgenumber` (`emp_badgenumber`),
KEY `emp_badgenumber_2` (`emp_badgenumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=111121326 ;
now change auto increment value and execute sql.