I need to use user-defined variable in an INSERT query for MySQL, see an example bellow:
INSERT INTO `posts`(`id`) VALUES(NULL);
SET #last_insert_id = LAST_INSERT_ID();
INSERT INTO `comments`(`id`, `post_id`) VALUES(NULL, "#last_insert_id");
This example doesn't work and inserted 0. What am I doing wrong?
There is no need to store it in a variable. You can just call LAST_INSERT_ID() inside the following INSERT statement.
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, LAST_INSERT_ID());
... unless you have multiple inserts to perform using that id.
In that case, the proper syntax for using the variable is to do so without quotes:
INSERT INTO `posts`(`id`) VALUES (NULL);
SET #last_insert_id = LAST_INSERT_ID();
/* Several new entries using the same #last_insert_id */
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, #last_insert_id);
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, #last_insert_id);
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, #last_insert_id);
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, #last_insert_id);
INSERT INTO `comments`(`id`, `post_id`) VALUES (NULL, #last_insert_id);
Related
Background: I am building a Springboot+mySQL app that uses Spring Data JPA native queries (i.e. #Query(value = "...", nativeQuery = true) to retrieve database data.
We have to use the same SQL in every query we write to enable certain functionality (this can be seen in the example below). And wanted a way to remove this duplicate SQL and instead only declare it once. An option presented was to pass a dynamic SQL string into a stored procedure and then build a prepared statement by concatenating this dynamic SQL string with our static shared SQL string (show in example below).
Question:
This doesn't seem like a good idea to me, but I am not knowledgeable enough about databases to given the exact technical reasons. Is the below example safe, reasonable, and best-practice? Are there ways to mitigate issues with this approach, or are there other approaches to use instead?
Basic setup code:
-- create tables
CREATE TABLE docs (
id INTEGER PRIMARY KEY,
rev INTEGER NOT NULL,
content VARCHAR(30) NOT NULL
);
CREATE TABLE more_docs (
id INTEGER PRIMARY KEY,
more_content VARCHAR(30) NOT NULL
);
CREATE TABLE docs_metadata (
id INTEGER PRIMARY KEY,
letter VARCHAR(30) NOT NULL
);
CREATE TABLE metadata_nums (
id INTEGER PRIMARY KEY,
metadata_id INTEGER,
num INTEGER NOT NULL
);
-- insert some values
INSERT INTO docs VALUES (1, 1, 'abc');
INSERT INTO docs VALUES (2, 1, 'def');
INSERT INTO docs VALUES (3, 2, 'ghi');
INSERT INTO docs VALUES (4, 1, 'jkl');
INSERT INTO more_docs VALUES (1, 'aaa');
INSERT INTO more_docs VALUES (2, 'bbb');
INSERT INTO more_docs VALUES (3, 'ccc');
INSERT INTO more_docs VALUES (4, 'ddd');
INSERT INTO docs_metadata VALUES (1, 'a');
INSERT INTO docs_metadata VALUES (2, 'b');
INSERT INTO docs_metadata VALUES (3, 'c');
INSERT INTO docs_metadata VALUES (4, 'd');
INSERT INTO metadata_nums VALUES (1, 1, 5);
INSERT INTO metadata_nums VALUES (2, 1, 6);
INSERT INTO metadata_nums VALUES (3, 2, 5);
INSERT INTO metadata_nums VALUES (4, 2, 6);
INSERT INTO metadata_nums VALUES (5, 3, 5);
INSERT INTO metadata_nums VALUES (6, 3, 6);
INSERT INTO metadata_nums VALUES (7, 4, 5);
INSERT INTO metadata_nums VALUES (8, 4, 6);
Approach in question:
-- create stored procedure
DELIMITER //
CREATE PROCEDURE FILTER_EVAL (IN dynamic_statement TEXT, IN num INT, IN letter VARCHAR(1))
BEGIN
SET #dynamic_statement := CONCAT("SELECT X.* FROM (", dynamic_statement, ") X INNER JOIN (SELECT DM.*, MN.num FROM docs_metadata DM INNER JOIN metadata_nums MN ON DM.id = MN.metadata_id) M ON X.id = M.id WHERE M.num = ", num, " AND M.letter = '", letter, "'");
PREPARE prepared_statement FROM #dynamic_statement;
EXECUTE prepared_statement;
DEALLOCATE PREPARE prepared_statement;
END//
DELIMITER ;
-- fetch some values
CALL FILTER_EVAL("SELECT * FROM docs WHERE rev = 1", 5, 'b')
Trigger definition:
BEGIN
INSERT INTO `user` (`ID`, `Username`, `Password`, `Online`) VALUES
(NEW.ID, "store_"NEW.ID , 'blablabla', 0);
END
In this trigger I have to insert as username something like store_(id of the new store).
Is it possible to do this and if yes how?
There are 2 ways to concat/append string in SQL
a. Use + operator to join the string
b. Use Concat function.
By using + operator the query would be like below.
BEGIN
INSERT INTO `user` (`ID`, `Username`, `Password`, `Online`) VALUES
(NEW.ID, "store_" + NEW.ID , 'blablabla', 0);
END
By using Concat() function the query would be like below.
BEGIN
INSERT INTO `user` (`ID`, `Username`, `Password`, `Online`) VALUES
(NEW.ID, Concat("store_",NEW.ID) , 'blablabla', 0);
END
Recommended option is use 'Concat' function as syntax is easier to follow, and the code looks cleaner
Use concat function :
BEGIN
INSERT INTO user (ID, Username, Password, Online)
VALUES
(NEW.ID, CONCAT('store_',NEW.ID), 'blablabla', 0);
END
I have a variable #ids = "894,891,896,899..."
What I like to do is the following
loop #id: #ids
INSERT INTO `testcases_types` (`testcase_id`, `type_id`) VALUES (#id, '57');
INSERT INTO `testcases_types` (`testcase_id`, `type_id`) VALUES (#id, '58');
INSERT INTO `testcases_types` (`testcase_id`, `type_id`) VALUES (#id, '59');
INSERT INTO `testcases_types` (`testcase_id`, `type_id`) VALUES (#id, '60');
end loop
So I tried a lot now , but I cannot find out the right syntax. I do not want to write a procedure. I just want to execute it once .
I want to to create 5 string sequential data like
aaaaa
aaaab
aaaac
.... upto
zzzzx
zzzzy
zzzzz
Does sql have any function that would help me with sequential data generation?
Currently I have four digits sequential data, how can I make generate five digit sequential data?
What i have
aaaa
aaab
aaac
....upto
zzzx
zzzy
zzzz
I wrote the following procedure but it takes forever to complete.. can anybody help me rewrite the procedure or advise a different approch.
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_procedure`()
BEGIN
DECLARE a INT Default 1 ;
DECLARE tran varchar(255) Default 'aaaa';
simple_loop: LOOP
SET a=a+1;
SET tran = (select fourth from m where idm=a);
Insert into test.qwe(zxc) values (CONCAT(tran,'a'));
Insert into test.qwe(zxc) values (CONCAT(tran,'b'));
Insert into test.qwe(zxc) values (CONCAT(tran,'c'));
Insert into test.qwe(zxc) values (CONCAT(tran,'d'));
Insert into test.qwe(zxc) values (CONCAT(tran,'e'));
Insert into test.qwe(zxc) values (CONCAT(tran,'f'));
Insert into test.qwe(zxc) values (CONCAT(tran,'g'));
Insert into test.qwe(zxc) values (CONCAT(tran,'h'));
Insert into test.qwe(zxc) values (CONCAT(tran,'i'));
Insert into test.qwe(zxc) values (CONCAT(tran,'j'));
Insert into test.qwe(zxc) values (CONCAT(tran,'k'));
Insert into test.qwe(zxc) values (CONCAT(tran,'l'));
Insert into test.qwe(zxc) values (CONCAT(tran,'m'));
Insert into test.qwe(zxc) values (CONCAT(tran,'n'));
Insert into test.qwe(zxc) values (CONCAT(tran,'o'));
Insert into test.qwe(zxc) values (CONCAT(tran,'p'));
Insert into test.qwe(zxc) values (CONCAT(tran,'q'));
Insert into test.qwe(zxc) values (CONCAT(tran,'r'));
Insert into test.qwe(zxc) values (CONCAT(tran,'s'));
Insert into test.qwe(zxc) values (CONCAT(tran,'t'));
Insert into test.qwe(zxc) values (CONCAT(tran,'u'));
Insert into test.qwe(zxc) values (CONCAT(tran,'v'));
Insert into test.qwe(zxc) values (CONCAT(tran,'w'));
Insert into test.qwe(zxc) values (CONCAT(tran,'x'));
Insert into test.qwe(zxc) values (CONCAT(tran,'y'));
Insert into test.qwe(zxc) values (CONCAT(tran,'z'));
IF a=1 THEN
LEAVE simple_loop;
END IF;
END LOOP simple_loop;
END
From scratch:
CREATE TABLE alpha (a CHAR(1) NOT NULL);
INSERT INTO alpha (a) VALUES
('a'), ('b'), ('c'), ('d'), ('e'), ('f'),
('g'), ('h'), ('i'), ('j'), ('k'), ('l'),
('m'), ('n'), ('o'), ('p'), ('q'), ('r'),
('s'), ('t'), ('u'), ('v'), ('w'), ('x'),
('y'), ('z');
CREATE TABLE qwe (zxc CHAR(5) NOT NULL);
INSERT INTO qwe (zxc)
SELECT CONCAT(a1.a, a2.a, a3.a, a4.a, a5.a)
FROM alpha a1, alpha a2, alpha a3, alpha a4, alpha a5;
If you already have all the strings of length 4 in a table, you can just join to alpha once and concatenate the values to generate all the strings of length 5. It's still going to take some time, no way around that.
The sql procedure I wrote worked.. It took around 4-5 hours to popoulta 26x26x26x26 combinations of 6 string words.
Thanks for all the suggestions !
I'm trying to get the following code to run in a MySQL Trigger but I get error 1064 when I try to save it.
SET #ma = (SELECT modem_alias FROM `play`.`veh` WHERE meid = new.org_a LIMIT 1);
INSERT INTO `play`.`des` (`indx`, `des_a`, `des_b`) VALUES (NULL, new.org_a, SELECT #ma);
The trigger is set to run on 'org' table after an INSERT
Don't use SELECT in the INSERT, just the variable:
INSERT INTO `play`.`des` (`indx`, `des_a`, `des_b`) VALUES (NULL, new.org_a, #ma);
You can also combine the two queries so you don't need a variable:
INSERT INTO play.des (indx, des_a, des_b)
SELECT NULL, new.org_a, modem_alias
FROM play.veh
WHERE meid = new.org_a
LIMIT 1
Your values is wrong: You can't select there, just use the variable itself:
INSERT ... VALUES (..., #ma);