Two questions.
I need to create a procedure called SITE_SP, to count the number of records in the 'SHOWSITE' table.
Then I need to run the site_sp procedure to display the number of records in the 'SHOWSITE' table. My guess here is with the EXEC site_sp.
So far, all I have is (I know it isn't correct but that's all I can do, i'm really stuck).
DROP PROCEDURE IF EXISTS site_sp;
CREATE PROCEDURE site_sp
BEGIN
Select * FROM showsite
END;
Any help appreciated. I've asked before but can't seem to get any positive feedback, so I skipped this question and did the others, but this one I just can't solve.
One solution should be to create a temporary table with your result in it:
DROP PROCEDURE IF EXISTS site_sp;
CREATE PROCEDURE site_sp BEGIN DROP TABLE IF EXISTS tmp_result;
CREATE TABLE tmp_result SELECT COUNT(*) FROM showsite END//
delimiter ;
Related
I want to create an trigger inside an procedure. but after some research I got to know that it is not possible. can u suggest me another way I can achieve the below actions. (I cant share exact data and queries due to some reason. please refer similar queries.)
What I want
I have created an temporary table containing data i need.
eg. CREATE TEMPORARY TABLE temp1 SELECT id, col_1 FROM table1 WHERE col_1=2;
I want to inset data in table table2 when data is inserted in temp1, which i can achieve by creating a TRIGGER. but the problem is I want to give a value in table2 which will be dynamic and will be taken from nodejs backend. so i created a PROCEDURE which takes parameter neededId. but i cant created trigger inside a procedure. is their any other way i can achieve this?
Procedure I Created
here neededId is the foreign key I get from backend to insert
DELIMITER $$
USE `DB`$$
CREATE PROCEDURE `MyProcedure` (IN neededID int)
BEGIN
DROP TABLE IF EXISTS temp1;
CREATE TEMPORARY TABLE temp1 SELECT id, col_1 FROM table1 WHERE col_1=2;
DROP TRIGGER IF EXISTS myTrigger;
CREATE TRIGGER myTrigger AFTER INSERT ON temp1 FOR EACH ROW
BEGIN
INSERT into table2("value1", "value2", neededId);
END;
END$$
DELIMITER ;
SQL Statements Not Permitted in Stored Routines
Generally, statements not permitted in SQL prepared statements are also not permitted in stored programs. ... Exceptions are SIGNAL, RESIGNAL, and GET DIAGNOSTICS, which are not permissible as prepared statements but are permitted in stored programs.
SQL Syntax Permitted in Prepared Statements
CREATE TRIGGER is not listed.
Finally: the trigger cannot be created in stored procedure, function, prepared statement, trigger or event procedure.
In MySQL, you can't create a trigger for a temporary table, regardless of whether you do it in a stored procedure or not.
https://dev.mysql.com/doc/refman/8.0/en/create-trigger.html says:
The trigger becomes associated with the table named tbl_name, which must refer to a permanent table. You cannot associate a trigger with a TEMPORARY table or a view.
I assume the same is true of MariaDB. It's not clear from your question which one you use. You say MySQL at first, but you tagged the question mariadb. Be aware that these are not the same database product, and they are not necessarily compatible.
Here's a demo of the error, tested on MySQL 8.0.28:
mysql> create temporary table t ( i int );
mysql> create trigger t before insert on t for each row set NEW.i = 42;
ERROR 1361 (HY000): Trigger's 't' is view or temporary table
So in your case, you cannot use a trigger for the temporary table. You'll have to think of a different way to implement inserts to your second table.
I'm using MySQL and trying to create a temp table. I will be doing a 2 while loop statements in PHP to populate the temp table. Firstly though I can't seem to get the Insert into temp table to work. I've tried many different versions of this, some using '#' for the table and various things (are there differences in SQL server and MySQL commands?). Here's my last attempt (P.S the Select statement works fine on its own).
CREATE TEMPORARY TABLE temp
(
aID varchar(15) NOT NULL,
bID varchar(15) NOT NULL
)
INSERT INTO temp
SELECT aID, bID
FROM tags
WHERE placeID = "abc" AND tagID = "def";
Help appreciated!
Also, just a general Q...this query will have to be run many times. Will using temp tables be OK or cause the server issues?
working on what Code-Monk wrote, consider the following:
drop procedure if exists uspK;
DELIMITER $$
create procedure uspK ()
BEGIN
drop temporary table if exists temp; -- could be some other random structure residue
create temporary table temp
SELECT aID, bID
FROM tags
WHERE placeID = "abc" AND tagID = "def";
-- use the temp table somehow
-- ...
-- ...
-- ...
drop temporary table temp; -- otherwise it survives the stored proc call
END
$$ -- signify end of block
DELIMITER ; -- reset to default delimiter
Test Stored Procedure
call uspK(); -- test it, no warnings on edge conditions
What not to do
One would not find much luck with the following. If you think so, run it a few times;
drop procedure if exists uspK;
DELIMITER $$
create procedure uspK ()
BEGIN
-- drop temporary table if exists temp;
create temporary table if not exists temp
SELECT aID, bID
FROM tags
WHERE placeID = "abc" AND tagID = "def";
-- use the temp table somehow
-- ...
-- ...
-- ...
-- drop temporary table temp; -- otherwise it survives the stored proc call
END
$$ -- signify end of block
DELIMITER ; -- reset to default delimiter
because create temporary table if not exists temp is flakey
General Comments
One should not embark into writing stored procs until somewhat fluent on the simple topic of DELIMITERS. Wrote about them in a section here called Delimiters. Just hoping to head you off from unnecessary wasted time on such a simple thing, than can waste a lot of debugging time.
Also, here in your question, as well as in that reference, keep in mind that the creation of tables is DDL that can have a large percentage of the overall profiling (performance). It slows down a proc versus using a pre-existing table. One might think the call is instantaneous, but it is not. As such, for performance, using a pre-existing table with ones results put into their own segmented rowId is much faster than enduring DDL overhead.
You can create temporary table and insert select statemet in following way:
create temporary table temp
SELECT aID, bID
FROM tags
WHERE placeID = "abc" AND tagID = "def";
To drop the temporary table before creating it again. put following statement before creating temporary table:
drop temporary table if exists temp;
Note: It will be good if you can put all this code in stored procedure. and call it to create temporary table.
I want to store the output from a PROCEDURE into a global userdefined VAR so i can use this "list" in an other PROCEDURE on a different database.
Second, if the VAR is used on the 2nd PROCEDURE it should be unset, because on next CALL it will append or?
Thanks for response!
BEGIN
SELECT `steamid` FROM `mybb_users` WHERE `steamid`!='';
END
The SELECT shout go into a global variable, so i can use the result in another procedure...
As far as I know, you can't return a row set as a result of a procedure in MySQL.
I would solve it by creating a temporary table in the first procedure, and then use that temp table in the second procedure. Something like this:
delimiter $$
create procedure procedure1()
begin
drop table if exists temp_table;
create temporary table temp_table
select steamid from mybb_users where steamid != '';
-- add the appropriate indexes here
-- alter table temp_table
-- add index ...
end $$
create procedure procedure2()
begin
-- Do whatever you want to do with temp_table
end $$
delimiter ;
Remember:
A temporary table is visible only to the connection that created it.
If the connection is closed, the temporary table will be deleted.
Temporary tables are created directly to RAM (if they are not very big), so they can be pretty fast to read.
Each connection can create temporary tables with the same name, as each connection will have a "copy" of that temp table.
I have a query like
Select id,name,... FROM table WHERE id IN (?)
The query is actually more complicated with joins and another (?) with the same ids. I've been told to put it on a stored procedure to make it easier to manage and safer, but mysql doesn't support arrays, so I'm not sure what is the best way to do it, considering that I don't know how many id I will have to pass. I have seen people passing a string. Is it the only way?
You can use temporary tables. Though this answer is not highly voted so I suppose that using a string parameter is the prefered way (17 votes vs 2 votes) (see the link). The answer with temporary table is taken from another question: Pass array to MySQL stored routine
Use a join with a temporary table. You don't need to pass temporary
tables to functions, they are global.
create temporary table ids( id int ) ;
insert into ids values (1),(2),(3) ;
delimiter //
drop procedure if exists tsel //
create procedure tsel() -- uses temporary table named ids. no params
READS SQL DATA
BEGIN
-- use the temporary table `ids` in the SELECT statement or
-- whatever query you have
select * from Users INNER JOIN ids on userId=ids.id ;
END //
DELIMITER ;
CALL tsel() ; -- call the procedure
I want to know how to use DROP TABLE IF EXISTS in a MySQLstored procedure.
I'm writing a rather long mySQL Stored Procedure that will do a bunch of work and then load up a temp table with the results. However, I am having trouble making this work.
I've seen a few ways to do the temp table thing. Basically, you either create the temp table, work on it, and then drop it at the end ... or you drop it if it exists, create it, and then do your work on it.
I prefer the second method so that you always start of clean, and it's a built-in check for the table's existence. However, I can't seem to get it to work:
Here are my examples:
This Works:
DELIMITER//
DROP PROCEDURE IF EXISTS pTest//
CREATE PROCEDURE pTest()
BEGIN
CREATE TEMPORARY TABLE tblTest (
OrderDate varchar(200)
);
DROP TEMPORARY TABLE tblTest;
END//
DELIMITER ;
CALL pTest();
This Works:
DELIMITER//
DROP PROCEDURE IF EXISTS pTest//
CREATE PROCEDURE pTest()
BEGIN
DROP TEMPORARY TABLE tblTest;
CREATE TEMPORARY TABLE tblTest (
OrderDate varchar(200)
);
END//
DELIMITER ;
CALL pTest();
This does not:
DELIMITER//
DROP PROCEDURE IF EXISTS pTest//
CREATE PROCEDURE pTest()
BEGIN
DROP TEMPORARY TABLE IF EXISTS tblTest;
CREATE TEMPORARY TABLE tblTest (
OrderDate varchar(200)
);
END//
DELIMITER ;
CALL pTest();
The first 2 work, but if that table exists (like if the procedure didn't finish or something), it'll obviously end with a "Table tblTest does not exist" error. The non-working example is what I'm looking for -- drop the table if its there and then recreate it so that I can start clean.
It feels like it's the "IF EXISTS" making this thing fail. I've copied code from all sorts of sites that do things very similar and in no case can I get a "DROP TABLE IF EXISTS..." to work. Ever.
Dev Server: mySQL Server version: 5.1.47-community
Prod Server: mySQL Server version: 5.0.45-log
We can't change db versions (DBAs won't allow it), so I'm stuck on what I have. Is this a bug in mySQL or in the Procedure?
Thanks.
It's an old question but it came up as I was looking for DROP TABLE IF EXISTS.
Your non-working code did not work on my MySQL 5.1.70 server.
All I had to do was add a space between DELIMITER and // on the first line, and everything worked fine.
Working code:
DELIMITER //
DROP PROCEDURE IF EXISTS pTest//
CREATE PROCEDURE pTest()
BEGIN
DROP TEMPORARY TABLE IF EXISTS tblTest;
CREATE TEMPORARY TABLE tblTest (
OrderDate varchar(200)
);
END//
DELIMITER ;
I don't know why this is not working for you,but you should be able to work around the issue using a continue handler. If you put the DROP TABLE statement into it's own BEGIN...END block you can use a continue handler to ignore the error if the table does not exist.
Try this:
DELIMITER //
DROP PROCEDURE IF EXISTS pTest //
CREATE PROCEDURE pTest()
BEGIN
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' BEGIN END;
DROP TEMPORARY TABLE tblTest;
END;
CREATE TEMPORARY TABLE tblTest (
OrderDate varchar(200)
);
END //
DELIMITER ;
CALL pTest();
I also had the same problem. It seems MySQL doesn't like to check if the table exists on some versions or something. I worked around the issue by querying the database first, and if I found a table I dropped it. Using PHP:
$q = #mysql_query("SELECT * FROM `$name`");
if ($q){
$q = mysql_query("DROP TABLE `$name`");
if(!$q) die('e: Could not drop the table '.mysql_error());
}
You suppress the error in the first query with the # symbol, so you don't have an interfering error, and then drop the table when the query returns false.
I recommend to add new line
SET sql_notes = 0// before DROP PROCEDURE IF EXISTS get_table //
Otherwise it will show warning PROCEDURE does not exists.