DELIMITER $
DROP PROCEDURE IF EXISTS CREATE_BACKUP$
CREATE PROCEDURE CREATE_BACKUP()
BEGIN
DECLARE BACK INT DEFAULT 0;
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'STUDENTDB'
;
SHOW_LOOP:LOOP
IF BACK = 1
THEN
LEAVE SHOW_LOOP;
END IF;
CREATE TABLE STUDENT_BACKUP
AS SELECT * FROM STUDENT;
CREATE TABLE SCORE_BACKUP
AS SELECT * FROM SCORE;
CREATE TABLE GRADE_EVENT_BACKUP
AS SELECT * FROM grade_event;
END LOOP SHOW_LOOP;
END$
DELIMITER ;
Hi, when I run this procedure, it runs more than one time. So I get an error which says "STUDENT_BACKUP table already exists" for the second time when it runs. What should I do to run it just 1 time?
In MySQL you can use CREATE TABLE IF NOT EXIST... to avoid the error occurrence. See CREATE TABLE syntax for details.
To solve your quesrion for SQL server use an INFORMATION_SCHEMA view. A similar solution is in the existing topic.
Related
This is the query i am using:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME =( N'CustomerVariable1Value'))
begin Alter table temp.DIM_BE_ACCOUNT drop column CustomerVariable1Value
It works fine the first time but when I run it again, it shows error.
How to make it error free and executes it many number of times?
Error message:
ALTER TABLE DROP COLUMN failed because column 'CustomerVariable1Value' does not exist in table 'DIM_BE_ACCOUNT'.
You are only looking for a column name out of all column names in the entire MySQL instance. You need to also filter by schema (=database) and table names:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = N'CustomerVariable1Value' AND TABLE_NAME = 'MyTableName' AND TABLE_SCHEMA = 'MyDatabase')
Here is a solution that does not involve querying INFORMATION_SCHEMA, it simply ignores the error if the column does not exist.
DROP PROCEDURE IF EXISTS `?`;
DELIMITER //
CREATE PROCEDURE `?`
(
)
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE `table_name` DROP COLUMN `column_name`;
END //
DELIMITER ;
CALL `?`();
DROP PROCEDURE `?`;
P.S. Feel free to give it other name rather than ?
I want to update a MySQL database schema (with MySQL code) but I am unfortunately not sure of the state of the tables, as they are distributed..
Let's say some 'clients' have a table called "user" with a schema like
name VARCHAR(64) NOT NULL
password VARCHAR(64) NOT NULL
I want to add an email column, but it's possible that they already have an email column (depending on their installation version).
How can I run a command that ensures that there is a email column and does nothing if it's already there? Keep in mind I would be doing this for many tables that are more complex.
I know I could be creating temp tables and re-populating (and will if it's the only solution) but I figure there might be some kind of CREATE or UPDATE table command that has "oh you already have that column, skip" logic.
You can try like this:
DELIMITER $$
CREATE PROCEDURE Alter_MyTable()
BEGIN
DECLARE _count INT;
SET _count = ( SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'user' AND
COLUMN_NAME = 'email');
IF _count = 0 THEN
ALTER TABLE user
ADD COLUMN email varchar(512);
END IF;
END $$
DELIMITER ;
or rather make it a generic stored procedure like this:
create procedure AddColumnIfDoesntExists(
IN dbName tinytext,
IN tableName tinytext,
IN fieldName tinytext,
IN fieldDef text)
begin
IF NOT EXISTS (
SELECT * FROM information_schema.COLUMNS
WHERE column_name=fieldName
and table_name=tableName
and table_schema=dbName
)
THEN
set #ddl=CONCAT('ALTER TABLE ',dbName,'.',tableName,
' ADD COLUMN ',fieldName,' ',fieldDef);
prepare stmt from #ddl;
execute stmt;
END IF;
end;
//
delimiter ';'
If the column already exists the ALTER TABLE ADD COLUMN statement will throw an error, so if you are thinking that you might lose data because of trying to add a column that already exists that won't be the case, if any you need to handle error. See add column to mysql table if it does not exist
There are also resources telling you how to deal with these with store procedures, etc. See MySQL add column if not exist.
Hope it helps.
The following procedure gives me an error when I invoke it using the CALL statement:
CREATE DEFINER=`user`#`localhost` PROCEDURE `emp_performance`(id VARCHAR(10))
BEGIN
DROP TEMPORARY TABLE IF EXISTS performance;
CREATE TEMPORARY TABLE performance AS
SELECT time_in, time_out, day FROM attendance WHERE employee_id = id;
END
The error says "Unknown table 'performance' ".
This is my first time actually using stored procedures and I got my sources from Google. I just cant figure out what I am doing wrong.
I've tidied it up a little for you and added example code. I always keep my parameter names the same as the fields they represent but prefix with p_ which prevents issues. I do the same with variables declared in the sproc body but prefix with v_.
You can find another one of my examples here:
Generating Depth based tree from Hierarchical Data in MySQL (no CTEs)
drop procedure if exists emp_performance;
delimiter #
create procedure emp_performance
(
in p_employee_id varchar(10)
)
begin
declare v_counter int unsigned default 0;
create temporary table tmp engine=memory select time_in, time_out
from attendance where employee_id = p_employee_id;
-- do stuff with tmp...
select count(*) into v_counter from tmp;
-- output and cleanup
select * from tmp order by time_in;
drop temporary table if exists tmp;
end#
delimiter ;
call emp_performance('E123456789');
By default MySQL config variable sql_notes is set to 1.
That means that
DROP TEMPORARY TABLE IF EXISTS performance;
increments warning_count by one and you get a warning when a stored procedure finishes.
You can set sql_notes variable to 0 in my.cnf or rewrite stored procedure like that:
CREATE DEFINER=`user`#`localhost` PROCEDURE `emp_performance`(id VARCHAR(10))
BEGIN
SET ##session.sql_notes = 0;
DROP TEMPORARY TABLE IF EXISTS performance;
CREATE TEMPORARY TABLE performance AS
SELECT time_in, time_out, day FROM attendance WHERE employee_id = id;
SET ##session.sql_notes = 1;
END
How do analyse and use EXPLAIN for my stored procedure calls ?
I need to optimize the query time, however seems like there is no where i can do a EXPLAIN call proc_name() ?
You can try
set profiling=1;
call proc_name();
show profiles;
at present you can't explain stored procedures in mysql - but you could do something like this:
drop procedure if exists get_user;
delimiter #
create procedure get_user
(
in p_user_id int unsigned,
in p_explain tinyint unsigned
)
begin
if (p_explain) then
explain select * from users where user_id = p_user_id;
end if;
select * from users where user_id = p_user_id;
end#
delimiter ;
call get_user(1,1);
EXPLAIN works only on SELECT statements, except when you use EXPLAIN tablename which is an alias of DESCRIBE tablename
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.