Mysql stored procedure insert into multiple tables - mysql

Am trying to insert data into 2 tables but only 1 table gets the data but the other one doesn't. I don't get any error messages but only the login table gets populated but the user doesn't.
Here is my code
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_user`(
_email varchar(50),
_password varchar(255),
_name varchar(35),
_surname varchar(35)
)
BEGIN
start transaction;
insert into logins_copy (
email,
password,
created_at,
updated_at
)
values
(
_email,
_password,
current_timestamp(),
current_timestamp()
);
SELECT #user_id := id from logins_copy where email = _email;
insert into users (
user_id,
name,
surname,
updated_at
)
values
(
#user_id,
_name,
_surname,
current_timestamp()
);
commit;
END
and to test this I called the procedure:
call `new_user`("test#hotmail.com", "test123", "Adam", "James");

Related

MySQL: insert procedure, with variable from another table

I have two tables:
CREATE TABLE userTypes (
id INTEGER NOT NULL PRIMARY KEY,
type VARCHAR(50) NOT NULL
);
CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(50) NOT NULL,
userTypeId INTEGER NOT NULL,
FOREIGN KEY (userTypeId) REFERENCES userTypes(id)
);
INSERT INTO userTypes (id, type) VALUES (0, 'free');
INSERT INTO userTypes (id, type) VALUES (1, 'paid');
I want to create a procedure where that it inserts a user in the users table, with :
id is auto incremented.
email is equal to the email parameter.
userTypeId is the id of the userTypes row whose type attribute is equal to the type parameter
The INSERT function doesn't work with WHERE, so I tried to add a UPDATE but it's not working. Here's what I have for the moment:
DELIMITER //
CREATE PROCEDURE insertUser(
IN type VARCHAR(50),
IN email VARCHAR(50)
)
BEGIN
INSERT INTO users(id, email, userTypeID) VALUES (LAST_INSERT_ID(), email, userTypeID);
UPDATE users SET users.userTypeID = usertypes.id
WHERE usertypes.type = type;
END//
DELIMITER ;
The expected result should be something like this:
CALL insertUser('free', 'name_1#mail.com');
CALL insertUser('paid', 'name_2#mail.com');
SELECT * FROM users;
id email userTypeId
------------------------------------------
1 name_1#mail.com 0
2 name_2#mail.com 1
Leave out the auto_increment-column. As the name suggests, the db will fill this automatically.
Then, use different names for the parameters than the column names. You can use a prefix with the parameters.
Additionally, you could consider using the userTypeId integer value as parameter instead of the textual value. Otherwise you need to handle the situation where the passed type is not among the types in the userTypes (create a new one/reject insert).
DELIMITER //
CREATE PROCEDURE insertUser(
in_type VARCHAR(50),
in_email VARCHAR(50)
)
BEGIN
INSERT INTO users(email, userTypeID)
SELECT in_email, id
FROM userTypes
WHERE type=in_type;
IF (ROW_COUNT()=0) THEN
SELECT 'Error';
ELSE
SELECT 'OK';
END IF;
END//
DELIMITER ;

I don't know what's wrong with my MYSQL procedure

to try to create a procedure in MYSQL workbench but I'm not succeeding ..
A procedure inserts into a table with parameters coming from an ASP program, inserts into the campaign table, then by the inserted ID, inserts into another table and returns the inserted id from that table in the last table.
What am I doing wrong? I'm getting used to SQL Server....
CREATE PROCEDURE Insert_Campaign_Indicator(
IN Name VARCHAR(50),
IN Email VARCHAR(50),
IN Phone VARCHAR(50),
IN Active INT,
IN Type INT,
IN UserId INT,
IN CampaignId INT
)
BEGIN
INSERT INTO Indicator(Name, Email, Phone, Link, Active, CleaningType, Type, UserId)
VALUES (Name, Email, Phone, uuid(), Active, 2, Type, UserId);
INSERT INTO CampaignIndicator (CampaignId, IndicatorId, Link, ResearchWasSent, ReadyToRefer, AcceptedRefer, Active, UserId)
VALUES (CampaignId, LAST_INSERT_ID(), uuid(),0,0,0, 1, UserId);
SELECT Link FROM CampaignIndicator WHERE Id = LAST_INSERT_ID();
END //
DELIMITER ;
Never use Column names as variable, MySQL gets confused
The code is without DELIMITER because of the dbfddle site you have to add them
CREATE TABLE Indicator(id int AUTO_INCREMENT PRIMARY KEY,Name VARCHAR(50)
, Email VARCHAR(50), Phone VARCHAR(50), Link VARCHAR(36),Active Int, CleaningType int, Type int, UserId int)
CREATE TABLE CampaignIndicator (id int AUTO_INCREMENT PRIMARY KEY,CampaignId int
, IndicatorId int, Link VARCHAR(36), ResearchWasSent int, ReadyToRefer int, AcceptedRefer int
, Active int, UserId int)
CREATE PROCEDURE Insert_Campaign_Indicator(
IN _Name VARCHAR(50),
IN _Email VARCHAR(50),
IN _Phone VARCHAR(50),
IN _Active INT,
IN _Type INT,
IN _UserId INT,
IN _CampaignId INT
)
BEGIN
INSERT INTO Indicator(Name, Email, Phone, Link, Active, CleaningType, Type, UserId)
VALUES (_Name, _Email, _Phone, uuid(), _Active, 2, _Type, _UserId);
INSERT INTO CampaignIndicator (CampaignId, IndicatorId, Link, ResearchWasSent, ReadyToRefer, AcceptedRefer, Active, UserId)
VALUES (_CampaignId, LAST_INSERT_ID(), uuid(),0,0,0, 1, _UserId);
SELECT Link FROM CampaignIndicator WHERE Id = LAST_INSERT_ID();
END
CALL Insert_Campaign_Indicator('A','B','C',1,1,1,1)
| Link |
| :----------------------------------- |
| 28aee8e1-d169-11eb-96e0-00163e64f9cc |
✓
db<>fiddle here

Get OUT paramater in mysql

DELIMITER //
CREATE PROCEDURE InsertUser
(
IN RoleID INT,
IN UserEmail VARCHAR(100),
IN UserPassword VARCHAR(250),
OUT ID INT
)
BEGIN
INSERT INTO useraccount
(
RoleID,
UserEmail,
UserPassword,
CreateDate
)
VALUES
(
RoleID,
UserEmail,
UserPassword,
CURRENT_TIMESTAMP
);
SET ID = (SELECT UserID FROM useraccount WHERE UserEmail = UserEmail);
END //
DELIMITER ;
I want to get OUT Parameter ID but when i execute this procedure i got the error message "Subquery returns more than 1 row" can you tell me my mistake?
Thank You
Your subquery is wrong here:
SELECT UserID FROM useraccount WHERE UserEmail = UserEmail
Here you are compare UserEmail with itself which is going to be true for every row in the table ith not null values.
I would suggest the better approach will be to change the name of your UserEmail IN parameter(lets say it to email) :
DELIMITER //
CREATE PROCEDURE InsertUser
(
IN RoleID INT,
IN email VARCHAR(100),
IN UserPassword VARCHAR(250),
OUT ID INT
)
BEGIN
INSERT INTO useraccount
(
RoleID,
UserEmail,
UserPassword,
CreateDate
)
VALUES
(
RoleID,
email ,
UserPassword,
CURRENT_TIMESTAMP
);
SET ID = (SELECT UserID FROM useraccount WHERE UserEmail = email);
END //
DELIMITER ;
Please try this. Hope you are making sure that 2 useraccounts dont have same email

Updating a date as part of a trigger?

I'm trying to keep a list of current content and archived content in my PHP Internet application. I want to be able to identify the content that as archived as having an enddate, and the content that is not archived as having no enddate. It would be ideal if I could create more paths, but I'm hoping to just start here.
The first thing I'm noticing is that I'm getting a syntax error at the " on line 1, but there is no double quote where I create the table. The second issue I'm having is the use of TIMESTAMP as a datatype. I tried to use CURRENT_TIMESTAMP for the startdate, and it returned syntax errors. The final problem I am having is with the trigger construction. I'm not able to get down far enough to troubleshoot it. As soon as I get past the references, I'll also try to troubleshoot that.
CREATE TABLE plan(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
startdate TIMESTAMP NOT NULL,
enddate TIMESTAMP);
CREATE TABLE level(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
description VARCHAR(500),
startdate TIMESTAMP NOT NULL,
enddate TIMESTAMP);
CREATE TABLE planIDxlevelID(
planID INT NOT NULL REFERENCES plan(id),
levelID INT NOT NULL REFERENCES level(id),
arXORcur ENUM('archive', 'current');
);
delimiter |
CREATE TRIGGER testref BEFORE INSERT ON plan
FOR EACH ROW BEGIN
INSERT INTO plan(id, plan, startdate, enddate)
SET id = LAST_INSERT_ID( id + 1), name = NEW.name, startdate = NEW.UTC_TIMESTAMP, enddate = NULL;
UPDATE plan(enddate) WHERE plan.id = OLD.id
SET enddate = UTC_TIMESTAMP;
INSERT INTO planIDxlevelID(planID, levelID, arXORcur)
SET planID = NEW.planID, levelID = OLD.levelID, arXORcur = current;
UPDATE planIDxlevelID(planID, levelID, arXORcur) WHERE planID = OLD.planID
SET planID = OLD.planID, levelID = OLD.levelID, arXORcur = archive;
END;
|
delimiter ;
INSERT INTO plan (name) VALUES
"Frogs", "Toys", "Trucks", "Nature", "Seasons",
"Construction", "Candy", "Rainbows", "Telephone", "Breakfasts";
TIMESTAMP vs DATETIME
This is a classic gotcha: TIMESTAMP is a special datatype that
is updated with "now" every time the row is touched, whether you update it to another value or leave it alone. What you want is DATETIME.
Next, you have numerous syntax and other errors. The following executes without error, however it may not now have the logic you want, but you can edit it to fix that:
CREATE TABLE plan (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
startdate DATETIME NOT NULL, -- changed TIMESTAMP to DATETIME
enddate DATETIME -- changed TIMESTAMP to DATETIME
);
CREATE TABLE level (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(32),
description VARCHAR(500),
startdate DATETIME NOT NULL, -- changed TIMESTAMP to DATETIME
enddate DATETIME -- changed TIMESTAMP to DATETIME
);
CREATE TABLE planIDxlevelID (
planID INT NOT NULL REFERENCES plan(id),
levelID INT NOT NULL REFERENCES level(id),
arXORcur ENUM('archive', 'current')
);
DROP TRIGGER IF EXISTS test_insert;
delimiter |
CREATE TRIGGER test_insert BEFORE INSERT ON plan
FOR EACH ROW BEGIN
INSERT INTO plan (id, plan, startdate)
values (LAST_INSERT_ID() + 1, NEW.name, NEW.UTC_TIMESTAMP());
INSERT INTO planIDxlevelID (planID, levelID, arXORcur)
values (NEW.ID, null, arXORcur = current);
END;|
delimiter ;
DROP TRIGGER IF EXISTS test_update;
delimiter |
CREATE TRIGGER test_update BEFORE UPDATE ON plan
FOR EACH ROW BEGIN
UPDATE plan SET
enddate = UTC_TIMESTAMP
WHERE plan.id = OLD.id;
UPDATE planIDxlevelID SET
planID = NEW.ID,
levelID = null,
arXORcur = archive
WHERE planID = OLD.ID;
END;|
delimiter ;
INSERT INTO plan (name) VALUES
("Frogs"), ("Toys"), ("Trucks"), ("Nature"), ("Seasons"),
("Construction"), ("Candy"), ("Rainbows"), ("Telephone"), ("Breakfasts");

MySQL: What's wrong with this CREATE PROCEDURE statement?

DROP PROCEDURE IF EXISTS CreateTopic;
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
INSERT INTO forum_topics (forum_id, user_id, title, language)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET #tid := LAST_INSERT_ID();
INSERT INTO forum_posts (topic_id, user_id, subject, content) VALUES (#tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (obj_id, user_id, type, action) VALUES (#tid, i_user_id, 'Topics', 'Topic Created');
END;
I'm not sure what's wrong with it. MySQL tells me all sorts of things are incorrect, it just doesn't want to be created. Also, the parameters are identical types and lengths to their respective tables.
It is your first ";" that breaks procedure definition and mysql thinks you are done and treats whatever goes after ";" as another query.
You have to use delimiter for stored procedures.
DELIMITER $$
DROP PROCEDURE IF EXISTS CreateTopic$$
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
INSERT INTO forum_topics (forum_id, user_id, title, language)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET #tid := LAST_INSERT_ID();
INSERT INTO forum_posts (topic_id, user_id, subject, content) VALUES (#tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (obj_id, user_id, type, action) VALUES (#tid, i_user_id, 'Topics', 'Topic Created');
END
$$
DELIMITER ;
There are a few problems. I hope I got them all:
DROP PROCEDURE IF EXISTS CreateTopic;
CREATE PROCEDURE CreateTopic
(
i_forum_id INT,
i_user_id INT,
i_title VARCHAR(255),
i_language VARCHAR(50),
i_content TEXT,
i_stickied TINYINT,
i_announce TINYINT,
i_closed TINYINT
)
BEGIN
DECLARE tid INT;
INSERT INTO forum_topics (`forum_id`, `user_id`, `title`, `language`)
VALUES (i_forum_id, i_user_id, i_title, i_language);
SET tid = LAST_INSERT_ID();
INSERT INTO forum_posts (`topic_id`, `user_id`, `subject`, `content`) VALUES (tid, i_user_id, i_title, i_content);
INSERT INTO core_logs (`obj_id`, `user_id`, `type`, `action`) VALUES (tid, i_user_id, 'Topics', 'Topic Created');
END;