there is no error but also doesn't show success
at first, it shows on only table registrations and not the registration_details, and now doesn't appear in both table.
set foreign_key_checks = 0;
drop procedure if exists createRegist;
delimiter //
create procedure createRegist()
begin
declare total_credit float;
declare registration_id INT;
declare credit float;
-- create first registration for student 1
set total_credit = 0;
insert into `student_regist`.`registrations` (`registration_id`, `student_id`,`total_credit`)
values (1, 1, total_credit);
SELECT LAST_INSERT_ID() INTO registration_id;
-- create registration detail 1
SELECT
`student_regist`.`courses`.`credit`
INTO credit FROM
`student_regist`.`courses`
WHERE
`student_regist`.`courses`.`course_id` = 1
LIMIT 1;
set total_credit = total_credit + credit;
insert into `student_regist`.`registration_details` (`registration_details_id`, `registration_id`, `course_id`, `semester`)
values (1, 1, 1, 1);
SELECT 'Success';
end//
delimiter ;
You have not provided nearly enough detail for us to provide any concrete answers. Adding the DDL for your tables to your question is the minimum required for a real answer.
That said, here are some suggestions.
We know nothing of the values you need to store in credit (and total_credit) but it seems likely that it should be DECIMAL, and not FLOAT. Searching decimal vs float on here returns Float vs Decimal in ActiveRecord as the first result.
If you are using MySQL Workbench the errors/warnings should be displayed in the Output Area (View -> Panels -> Show Output Area). Or you could run SHOW WARNINGS; after calling your SP.
CALL createRegist();
SHOW WARNINGS;
Your first insert into registrations uses a hardcoded value of 1 for registration_id, which is presumably the primary key (PK) for the table. The second time you execute the SP and it tries to insert 1 into your PK, it will fail with a duplicate key error -
Error Code: 1062. Duplicate entry '1' for key 'registrations.PRIMARY'
You then follow up with the call for LAST_INSERT_ID() which will not work as you are expecting. From the MySQL docs -LAST_INSERT_ID()
The value of LAST_INSERT_ID() is not changed if you set the AUTO_INCREMENT column of a row to a non-“magic” value (that is, a value that is not NULL and not 0).
Changing the value passed in the insert statement to NULL or 0 (or removing completely) will resolve this -
/* Passing in value of NULL */
set total_credit = 0;
insert into `student_regist`.`registrations` (`registration_id`, `student_id`,`total_credit`)
values (NULL, 1, total_credit);
/* or removing completely */
set total_credit = 0;
insert into `student_regist`.`registrations` (`student_id`,`total_credit`)
values (1, total_credit);
Related
Why is the data not being inserted on the table when I execute the procedure, what seems to be lacking with the code?
I'm testing the procedure on phpMyAdmin > myDatabase > Procedures "Routines Tab" and clicking "Execute", prompts with a modal and ask for the values of "#idproc and #nameproc.
I tried with just the INSERT code it works, but when I add the IF condition it doesn't work.
Using XAMPP 8.0.3,
10.4.18-MariaDB
DELIMITER $$
CREATE DEFINER=`root`#`localhost:3307` PROCEDURE `testproc`(IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
IF #idproc = 0 THEN
INSERT INTO testproc(
id,
name)
VALUES(
#idproc,
#nameproc
);
ELSE
UPDATE testproc
SET
id = #idproc,
name = #nameproc
WHERE id = #idproc;
END IF;
SELECT * FROM testproc;
END$$
DELIMITER ;
You mix local variables (their names have not leading #) and user-defined variables (with single leading #). This is two different variable types, with different scopes and datatype rules. Procedure parameters are local variables too.
So when you use UDV which was not used previously you receive NULL as its value - and your code works incorrectly. Use LV everywhere:
CREATE DEFINER=`root`#`localhost:3307`
PROCEDURE `testproc` (IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
IF idproc = 0 THEN
INSERT INTO testproc (name) VALUES (nameproc);
ELSE
UPDATE testproc SET name = nameproc WHERE id = idproc;
END IF;
SELECT * FROM testproc;
END
You do not check does specified idproc value exists in the table. If it is specified (not zero) but not exists then your UPDATE won't update anything. Assuming that id is autoincremented primary key of the table I recommend to use
CREATE DEFINER=`root`#`localhost:3307`
PROCEDURE `testproc` (IN `idproc` INT, IN `nameproc` VARCHAR(100))
BEGIN
INSERT INTO testproc (id, name)
VALUES (idproc, nameproc)
ON DUPLICATE KEY
UPDATE name = VALUES(name);
SELECT * FROM testproc;
END
If specified idproc value exists in id column the row will be updated, if not then the new row will be inserted.
Additionally - I recommend you to provide NULL value instead of zero when you want to insert new row with specified nameproc value. NULL always cause autoincremented primary key generation whereas zero needs in specific server option setting.
how to inset into mysql table,example INSERT INTO users(user_id,time,)VALUES(1-500,1524275145) in my case need insert into TABLE users 500 rows form 1-500(it's users id) with same values time for all users.
I tried this one, it is working:
First you execute this snippet to create a procedure in your database so that we can call it later (the second snippet) and execute the query that will insert the 1-500 values into the users user_id column. (You can see the two variables that have values of 500 and 1, and you can see the line: VALUES (user_id_val, 1524275145) where the query will be executed.)
First snippet: (try to execute it separately from the next one)
DROP PROCEDURE IF EXISTS insert_loop;
DELIMITER #
CREATE PROCEDURE insert_loop()
BEGIN
DECLARE user_id_max INT UNSIGNED DEFAULT 500;
DECLARE user_id_val INT UNSIGNED DEFAULT 1;
START transaction;
WHILE user_id_val < user_id_max+1 DO
INSERT INTO users (user_id, time)
VALUES (user_id_val, 1524275145);
SET user_id_val = user_id_val + 1;
END WHILE;
COMMIT;
END #
Second snippet:
DELIMITER ;
CALL insert_loop();
Execute this after the first one (separately).
An example query for your case would be like this:
INSERT INTO users (user_id,time) VALUES
(1, 1524275145),
(2, 1524275145),
(3, 1524275145),
(4, 1524275145);
And so on, until 500. The best approach would be to create the query in a for loop.
I'm in my first databases class and I'm trying to write a conditional block for a mysql procedure.
This is the procedure:
delimiter //
CREATE PROCEDURE add_ascent(IN cid INT, IN pid INT)
BEGIN
DECLARE count_ascents INT;
SET count_ascents = 0;
SELECT COUNT(`cid`) INTO count_ascents FROM ascents WHERE `cid`=cid AND `pid`=pid;
IF count_ascents < 1 THEN
INSERT INTO ascents (`cid`, `pid`) VALUES (cid, pid);
UPDATE climbers SET climbers.ascents = climbers.ascents + 1 WHERE climbers.id=cid;
UPDATE problems SET problems.ascents = problems.ascents + 1 WHERE problems.id=pid;
END IF;
END;
//
delimiter ;
The goal of the procedure is to only perform the insert and updates if the (cid, pid) pair is not in the the ascents database. After testing, the program doesn't seem to go into the if block at all.
FYI, you might want to consider using an UPSERT, instead of "select/if/insert". For example, mySQL offers INSERT ON DUPLICATE KEY UPDATE.
Here, I suggest:
giving your parameters a DIFFERENT name than the column name, for example iCid and iPid, then
Typing SELECT COUNT(cid) INTO count_ascents FROM ascents WHERE cid=iCid AND pid=iPid and checking the result.
I am trying to convert this tsql to mysql but showing error need help
CREATE PROCEDURE FormAdd
#formName varchar(MAX)
AS
IF NOT EXISTS(SELECT * FROM tbl_Form WHERE formName=#formName)
BEGIN
INSERT INTO tbl_Form
(formName)
VALUES
(#formName)
SELECT ##identity
END
ELSE
BEGIN
SELECT '-1'
END
mysql
CREATE PROCEDURE FormAdd
(p_formName varchar(500) )
begin
INSERT INTO tbl_Form (formName)
VALUES (p_formName)
where NOT EXISTS(SELECT * FROM tbl_Form WHERE formName=p_formName) ;
SELECT Last_insert_id() as returnvalue ;
SELECT '-1' ;
end
Your attempt was syntactically invalid because logically, an INSERT statement cannot contain a WHERE clause since it does not act on existing rows.
If the purpose is to insert only if the value for p_formname is not already present, then an appropriate step would be to define a unique index on that column first. Then, construct your procedure to attempt the insert and inspect the ROW_COUNT() value to see if one was inserted and act accordingly, returning -1 if not to adapt your existing T-SQL procedure.
First create the unique index on p_formname:
ALTER TABLE tbl_Form ADD UNIQUE KEY `idx_formName` (`formName`);
Then your procedure should use INSERT INTO...ON DUPLICATE KEY UPDATE to attempt to insert the row. Per the documentation, the value of ROW_COUNT() will be 0 if a new row was not inserted or 1 if it was.
CREATE PROCEDURE FormAdd (p_formName varchar(500))
BEGIN
/* Attempt the insert, overwrite with the same value if necessary */
INSERT INTO tbl_Form (formName) VALUES (p_formName) ON DUPLICATE KEY UPDATE formName = p_formName;
/* Return the LAST_INSERT_ID() for a new row and -1 otherwise */
SELECT
CASE
WHEN ROW_COUNT() = 1 THEN LAST_INSERT_ID()
ELSE -1
END AS returnValue;
END
I am trying to understand why this trigger keeps giving me an error about invalid use of grouped function when i try to run a basin insert statement to test this out.
I have tried working with this to figure out what i am doing wrong but the error just remains the same. Error 1111
DROP TRIGGER a_num;
DELIMITER //
CREATE TRIGGER a_num BEFORE INSERT ON test_a
FOR EACH ROW BEGIN
DECLARE last INT DEFAULT 0;
INSERT INTO test_b SET full_name = CONCAT_WS(' ', NEW.f_name, NEW.l_name);
SET last = COUNT(id);
UPDATE test_b SET number = CONCAT_WS('-', last, LEFT(NEW.f_name, 2), LEFT(NEW.f_name, 2)) WHERE id = last;
END;
//
Please don't mind the use or poor construction I quite a newb.
Thanks.
I think it should be -
DROP TRIGGER a_num;
DELIMITER //
CREATE TRIGGER a_num BEFORE INSERT ON test_a
FOR EACH ROW BEGIN
DECLARE last INT DEFAULT 0;
INSERT INTO test_b SET full_name = CONCAT_WS(' ', NEW.f_name, NEW.l_name);
SET last = LAST_INSERT_ID();
UPDATE test_b SET number = CONCAT_WS('-', last, LEFT(NEW.f_name, 2), LEFT(NEW.f_name, 2)) WHERE id = last;
END;
//
Can you provide the CREATE statement for test_a and the INSERT statement you're using?
In MySQL Workbench if you right click on test_a go to Copy to Clipboard..Create Statement, will send the table definition.
Is there a reason you're inserting and then updating the same record? Could you combine this into one insert?