MySQL Procedure: If column don't exists create it - mysql

I try to make procedure that create non-exists column in my MySQL table like here:
MySQL add column if not exist
My procedure:
DELIMITER $$
CREATE PROCEDURE Alter_Table(IN _table_name TEXT,IN _column_name TEXT,IN _column_type TEXT)
BEGIN
DECLARE _count INT;
SET _count = ( SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = _table_name AND
COLUMN_NAME = _column_name);
IF _count = 0 THEN
ALTER TABLE _table_name ADD COLUMN _column_name _column_type;
END IF;
END $$
DELIMITER ;
But I have an error:
#1064 - Something is wrong in your syntax obok '_column_type; END IF; END' w linii 9
Anyone know why?

Ok... I make it in PHP...
function alter_table($table_name, $column_name, $column_type) {
$result = mysql_query("SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = `$table_name` AND COLUMN_NAME = `$column_name`");
if(!$result) {
mysql_query("ALTER TABLE `$table_name`
ADD COLUMN `$column_name` $column_type");
}
}

Related

ERROR 1064 (42000) / Wrong SQL Syntax but i dont know why? [duplicate]

I have this code:
ALTER TABLE `settings`
ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1
And I want to alter this table only if this column doesn't exist.
I'm trying a lot of different ways, but nothing works:
ALTER TABLE `settings`
ADD COLUMN IF NOT EXISTS `multi_user` TINYINT(1) NOT NULL DEFAULT 1
With procedure:
DELIMITER $$
CREATE PROCEDURE Alter_Table()
BEGIN
DECLARE _count INT;
SET _count = ( SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'settings' AND
COLUMN_NAME = 'multi_user');
IF _count = 0 THEN
ALTER TABLE `settings` ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1
END IF;
END $$
DELIMITER ;
I got error in END IF, then in END and then in 1
How can I make this as simple as possible?
Use the following in a stored procedure:
IF NOT EXISTS( SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tablename'
AND table_schema = 'db_name'
AND column_name = 'columnname') THEN
ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0';
END IF;
Use PREPARE/EXECUTE and querying the schema.
The host doesn't need to have permission to create or run procedures :
SET #dbname = DATABASE();
SET #tablename = "tableName";
SET #columnname = "colName";
SET #preparedStatement = (SELECT IF(
(
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(table_name = #tablename)
AND (table_schema = #dbname)
AND (column_name = #columnname)
) > 0,
"SELECT 1",
CONCAT("ALTER TABLE ", #tablename, " ADD ", #columnname, " INT(11);")
));
PREPARE alterIfNotExists FROM #preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
Here is a solution that does not involve querying INFORMATION_SCHEMA, it simply ignores the error if the column does exist.
DROP PROCEDURE IF EXISTS `?`;
DELIMITER //
CREATE PROCEDURE `?`()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE `table_name` ADD COLUMN `column_name` INTEGER;
END //
DELIMITER ;
CALL `?`();
DROP PROCEDURE `?`;
P.S. Feel free to give it other name rather than ?
Add field if not exist:
CALL addFieldIfNotExists ('settings', 'multi_user', 'TINYINT(1) NOT NULL DEFAULT 1');
addFieldIfNotExists code:
DELIMITER $$
DROP PROCEDURE IF EXISTS addFieldIfNotExists
$$
DROP FUNCTION IF EXISTS isFieldExisting
$$
CREATE FUNCTION isFieldExisting (table_name_IN VARCHAR(100), field_name_IN VARCHAR(100))
RETURNS INT
RETURN (
SELECT COUNT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = table_name_IN
AND COLUMN_NAME = field_name_IN
)
$$
CREATE PROCEDURE addFieldIfNotExists (
IN table_name_IN VARCHAR(100)
, IN field_name_IN VARCHAR(100)
, IN field_definition_IN VARCHAR(100)
)
BEGIN
SET #isFieldThere = isFieldExisting(table_name_IN, field_name_IN);
IF (#isFieldThere = 0) THEN
SET #ddl = CONCAT('ALTER TABLE ', table_name_IN);
SET #ddl = CONCAT(#ddl, ' ', 'ADD COLUMN') ;
SET #ddl = CONCAT(#ddl, ' ', field_name_IN);
SET #ddl = CONCAT(#ddl, ' ', field_definition_IN);
PREPARE stmt FROM #ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END;
$$
this is not original, but it IS copy-and-paste
source: javajon.blogspot.com/2012/10/
I used this approach (Without using stored procedure):
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tbl_name' AND COLUMN_NAME = 'column_name'
If it didnt return any rows then the column doesn't exists then alter the table:
ALTER TABLE tbl_name
ADD COLUMN column_name TINYINT(1) NOT NULL DEFAULT 1
Hope this helps.
hope this will help you
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
AND table_schema = 'db_name'
AND column_name = 'column_name'
or
delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='new_column' AND TABLE_NAME='tablename' AND TABLE_SCHEMA='the_schema'
)
THEN
ALTER TABLE `the_schema`.`the_table`
ADD COLUMN `new_column` TINYINT(1) NOT NULL DEFAULT 1;;
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;
$sql="SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Your_Table_Name' AND COLUMN_NAME = 'Your_New_Column_Name'";
$RESULT = mysqli_query($conn,$sql);
The abobe query return 0 if the column is not present in your table then you need to run alter query like below
if($RESULT){
$sqll="ALTER TABLE Your_table_Name ADD COLUMN Your_New_Column_Name varchar(20) NOT NULL DEFAULT 0";
}
SET #dbname = DATABASE();
SET #tablename = "table";
SET #columnname = "fieldname";
SET #preparedStatement = (SELECT IF(
(
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(table_name = #tablename)
AND (table_schema = #dbname)
AND (column_name = #columnname)
) > 0,
"SELECT 1",
CONCAT("ALTER TABLE ", #tablename, " ADD ", #columnname, " DECIMAL(18,4) NULL;")
));
PREPARE alterIfNotExists FROM #preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
This below worked for me:
SELECT count(*)
INTO #exist
FROM information_schema.columns
WHERE table_schema = 'mydatabase'
and COLUMN_NAME = 'mycolumn'
AND table_name = 'mytable' LIMIT 1;
set #query = IF(#exist <= 0, 'ALTER TABLE mydatabase.`mytable` ADD COLUMN `mycolumn` MEDIUMTEXT NULL',
'select \'Column Exists\' status');
prepare stmt from #query;
EXECUTE stmt;
Sometimes it may happen that there are multiple schema created in a database.
So to be specific schema we need to target, so this will help to do it.
SELECT count(*) into #colCnt FROM information_schema.columns WHERE table_name = 'mytable' AND column_name = 'mycolumn' and table_schema = DATABASE();
IF #colCnt = 0 THEN
ALTER TABLE `mytable` ADD COLUMN `mycolumn` VARCHAR(20) DEFAULT NULL;
END IF;
Using this as an example:
https://dbabulletin.com/index.php/2018/03/29/best-practices-using-flyway-for-database-migrations/
DELIMITER $$
DROP PROCEDURE IF EXISTS upgrade_database_4_to_5 $$
CREATE PROCEDURE upgrade_database_4_to_5()
BEGIN
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
AND COLUMN_NAME='multi_user' AND TABLE_NAME='settings') ) THEN
ALTER TABLE `settings` ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1;
END IF;
END $$
CALL upgrade_database_4_to_5() $$
DELIMITER ;

What is the correct syntax of IF NOT EXISTS in MySQL 5.7.25? [duplicate]

I have this code:
ALTER TABLE `settings`
ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1
And I want to alter this table only if this column doesn't exist.
I'm trying a lot of different ways, but nothing works:
ALTER TABLE `settings`
ADD COLUMN IF NOT EXISTS `multi_user` TINYINT(1) NOT NULL DEFAULT 1
With procedure:
DELIMITER $$
CREATE PROCEDURE Alter_Table()
BEGIN
DECLARE _count INT;
SET _count = ( SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'settings' AND
COLUMN_NAME = 'multi_user');
IF _count = 0 THEN
ALTER TABLE `settings` ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1
END IF;
END $$
DELIMITER ;
I got error in END IF, then in END and then in 1
How can I make this as simple as possible?
Use the following in a stored procedure:
IF NOT EXISTS( SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tablename'
AND table_schema = 'db_name'
AND column_name = 'columnname') THEN
ALTER TABLE `TableName` ADD `ColumnName` int(1) NOT NULL default '0';
END IF;
Use PREPARE/EXECUTE and querying the schema.
The host doesn't need to have permission to create or run procedures :
SET #dbname = DATABASE();
SET #tablename = "tableName";
SET #columnname = "colName";
SET #preparedStatement = (SELECT IF(
(
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(table_name = #tablename)
AND (table_schema = #dbname)
AND (column_name = #columnname)
) > 0,
"SELECT 1",
CONCAT("ALTER TABLE ", #tablename, " ADD ", #columnname, " INT(11);")
));
PREPARE alterIfNotExists FROM #preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
Here is a solution that does not involve querying INFORMATION_SCHEMA, it simply ignores the error if the column does exist.
DROP PROCEDURE IF EXISTS `?`;
DELIMITER //
CREATE PROCEDURE `?`()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
ALTER TABLE `table_name` ADD COLUMN `column_name` INTEGER;
END //
DELIMITER ;
CALL `?`();
DROP PROCEDURE `?`;
P.S. Feel free to give it other name rather than ?
Add field if not exist:
CALL addFieldIfNotExists ('settings', 'multi_user', 'TINYINT(1) NOT NULL DEFAULT 1');
addFieldIfNotExists code:
DELIMITER $$
DROP PROCEDURE IF EXISTS addFieldIfNotExists
$$
DROP FUNCTION IF EXISTS isFieldExisting
$$
CREATE FUNCTION isFieldExisting (table_name_IN VARCHAR(100), field_name_IN VARCHAR(100))
RETURNS INT
RETURN (
SELECT COUNT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = table_name_IN
AND COLUMN_NAME = field_name_IN
)
$$
CREATE PROCEDURE addFieldIfNotExists (
IN table_name_IN VARCHAR(100)
, IN field_name_IN VARCHAR(100)
, IN field_definition_IN VARCHAR(100)
)
BEGIN
SET #isFieldThere = isFieldExisting(table_name_IN, field_name_IN);
IF (#isFieldThere = 0) THEN
SET #ddl = CONCAT('ALTER TABLE ', table_name_IN);
SET #ddl = CONCAT(#ddl, ' ', 'ADD COLUMN') ;
SET #ddl = CONCAT(#ddl, ' ', field_name_IN);
SET #ddl = CONCAT(#ddl, ' ', field_definition_IN);
PREPARE stmt FROM #ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END;
$$
this is not original, but it IS copy-and-paste
source: javajon.blogspot.com/2012/10/
I used this approach (Without using stored procedure):
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tbl_name' AND COLUMN_NAME = 'column_name'
If it didnt return any rows then the column doesn't exists then alter the table:
ALTER TABLE tbl_name
ADD COLUMN column_name TINYINT(1) NOT NULL DEFAULT 1
Hope this helps.
hope this will help you
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'tbl_name'
AND table_schema = 'db_name'
AND column_name = 'column_name'
or
delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='new_column' AND TABLE_NAME='tablename' AND TABLE_SCHEMA='the_schema'
)
THEN
ALTER TABLE `the_schema`.`the_table`
ADD COLUMN `new_column` TINYINT(1) NOT NULL DEFAULT 1;;
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;
$sql="SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Your_Table_Name' AND COLUMN_NAME = 'Your_New_Column_Name'";
$RESULT = mysqli_query($conn,$sql);
The abobe query return 0 if the column is not present in your table then you need to run alter query like below
if($RESULT){
$sqll="ALTER TABLE Your_table_Name ADD COLUMN Your_New_Column_Name varchar(20) NOT NULL DEFAULT 0";
}
SET #dbname = DATABASE();
SET #tablename = "table";
SET #columnname = "fieldname";
SET #preparedStatement = (SELECT IF(
(
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE
(table_name = #tablename)
AND (table_schema = #dbname)
AND (column_name = #columnname)
) > 0,
"SELECT 1",
CONCAT("ALTER TABLE ", #tablename, " ADD ", #columnname, " DECIMAL(18,4) NULL;")
));
PREPARE alterIfNotExists FROM #preparedStatement;
EXECUTE alterIfNotExists;
DEALLOCATE PREPARE alterIfNotExists;
This below worked for me:
SELECT count(*)
INTO #exist
FROM information_schema.columns
WHERE table_schema = 'mydatabase'
and COLUMN_NAME = 'mycolumn'
AND table_name = 'mytable' LIMIT 1;
set #query = IF(#exist <= 0, 'ALTER TABLE mydatabase.`mytable` ADD COLUMN `mycolumn` MEDIUMTEXT NULL',
'select \'Column Exists\' status');
prepare stmt from #query;
EXECUTE stmt;
Sometimes it may happen that there are multiple schema created in a database.
So to be specific schema we need to target, so this will help to do it.
SELECT count(*) into #colCnt FROM information_schema.columns WHERE table_name = 'mytable' AND column_name = 'mycolumn' and table_schema = DATABASE();
IF #colCnt = 0 THEN
ALTER TABLE `mytable` ADD COLUMN `mycolumn` VARCHAR(20) DEFAULT NULL;
END IF;
Using this as an example:
https://dbabulletin.com/index.php/2018/03/29/best-practices-using-flyway-for-database-migrations/
DELIMITER $$
DROP PROCEDURE IF EXISTS upgrade_database_4_to_5 $$
CREATE PROCEDURE upgrade_database_4_to_5()
BEGIN
IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
AND COLUMN_NAME='multi_user' AND TABLE_NAME='settings') ) THEN
ALTER TABLE `settings` ADD COLUMN `multi_user` TINYINT(1) NOT NULL DEFAULT 1;
END IF;
END $$
CALL upgrade_database_4_to_5() $$
DELIMITER ;

Loop through array in mysql Stored procs

I need to dynamically alter set of tables
Currently i can alter only one using below SP.
DROP PROCEDURE IF EXISTS add_version_to_actor;
DELIMITER $$
CREATE DEFINER=CURRENT_USER PROCEDURE add_version_to_actor (IN table_name VARCHAR(40) )
BEGIN
DECLARE colName TEXT;
SELECT column_name INTO colName
FROM information_schema.columns
WHERE table_schema = 'database_name'
AND table_name = table_name
AND column_name = 'column';
IF colName is null THEN
Alter Table database_name.table_name ADD `sequence` INT( 10 ) NOT NULL;
END IF;
END$$
DELIMITER ;
CALL add_version_to_actor('table1');
DROP PROCEDURE add_version_to_actor;
Currently 'table1' is a single parameter. I need to pass multiple table names as string like this CALL add_version_to_actor('table1','table2');and loop through all of them.How can this be achieved.
Thanks in advance.

How can i insert a information_schema inside a stored proceedure

guys im quite new to stored proceedures. can anyone guide me on how to put the following simple sql query inside a stored proceedure
$tables = mysql_query("SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'Fogdb' AND table_name LIKE 'fdb_table_%' ");
i tried like below but it dint work
DELIMITER $$
DROP PROCEDURE IF EXISTS `alter_test_1`$$
CREATE DEFINER=`Fogdb`#`10.%` PROCEDURE `alter_test_1`()
BEGIN
SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'Fogdb' AND table_name LIKE 'fdb_table_%'
END$$
DELIMITER ;
try this:
create procedure test()
begin
SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'Fogdb' AND table_name LIKE 'fdb_table_%';
end
In your script, You have forget to put ';' at end of query;
Now try
DELIMITER $$
DROP PROCEDURE IF EXISTS `alter_test_1`$$
CREATE DEFINER=`adtracker`#`10.%` PROCEDURE `alter_test_1`()
BEGIN
SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'Fogdb' AND table_name LIKE 'fdb_table_%' ;
END$$
DELIMITER ;

MySQL IF THEN condition to Drop a table

I am trying to use stored procedure and check on a particular table and use IF THEN condition to drop the table. Is it possible to issue the DROP statement in the conditional block?
delimiter $$
CREATE PROCEDURE FC_SQLF()
BEGIN
DECLARE SQLFOUND int;
SET #SQLFOUND = (select count(table_name) from information_schema.tables where table_schema = 'testdb' and table_name = 'temp_table');
IF #SQLFOUND = 1 THEN DROP TABLE testdb.abcd;
END IF;
END $$