How to drop multiple databases based on a prefix string - mysql-management

example_ or e_
I want to drop all databases that match the prefix e_, so that e_database1, e_database2 and so forth are dropped.
Commands that do not work:
mysql drop database e_%
mysql drop database e_*
I'm not looking for all the tables in a given database, but all the databases in a given MySQL server.

You could do this with a stored proc like this:
/* Start stored proc */
DELIMITER //
DROP PROCEDURE IF EXISTS db_clean_up //
CREATE PROCEDURE db_clean_up
(
)
BEGIN
declare done bit default false;
declare deleted varchar(255);
-- Drop DBs
DECLARE cur1 CURSOR FOR SELECT
SCHEMA_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME LIKE 'db_prefix%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
createLoop: LOOP
FETCH cur1 INTO deleted;
IF done THEN
LEAVE createLoop;
END IF;
SET #query = CONCAT('DROP DATABASE `', deleted, '`;');
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
END LOOP createLoop;
CLOSE cur1;
END //
delimiter ;
/* End stored proc */

Related

Stored Procedure returns "Error Code: 1054. Unknown column 'schema.table.col' in 'field list'" when Creating different temporary table on same session

When using a stored procedure to dynamically generate a table based on configuration and return a result set (SELECT) with the records in that table, the second call to that procedure to generate a different table structure returns no records and it reports a missing column from a previous temporary table of the same name.
I tried this with MariaDB 10.3 and 10.1.21 and received the same result. I have minimized my code here to the minimum to demonstrate the error after trying several variations of single and multiple sub-procedures.
I also tried using some transaction control with COMMITS after executing the process, before trying to start the process with a different parameter, but got the same results.
DROP PROCEDURE IF EXISTS CreateATable;
DELIMITER $$
CREATE PROCEDURE CreateATable( _TableType tinyint )
BEGIN
DROP TEMPORARY TABLE IF EXISTS aTable;
IF _TableType = 1 THEN
SET #SQL_Statement :=
CONCAT(
'CREATE TEMPORARY TABLE aTable (',
'the_id bigint, ',
'the_column varchar(100) ',
') engine=INNODB',
';');
ELSE
SET #SQL_Statement :=
CONCAT(
'CREATE TEMPORARY TABLE aTable (',
'the_id bigint, ',
'the_other_column varchar(100) ',
') engine=INNODB',
';');
END IF;
PREPARE stmtCreateTable FROM #SQL_Statement;
EXECUTE stmtCreateTable;
DEALLOCATE PREPARE stmtCreateTable;
SET #SQL_Statement := NULL;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS GetATable;
DELIMITER $$
CREATE PROCEDURE GetATable()
BEGIN
CALL CreateATable( 1 );
SELECT * FROM aTable;
CALL CreateATable( 2 );
SELECT * FROM aTable;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS GetATable2;
DELIMITER $$
CREATE PROCEDURE GetATable2(_TableType tinyint)
BEGIN
CALL CreateATable( _TableType );
SELECT * FROM aTable;
END$$
DELIMITER ;
/*
Test execution script starts here
*/
-- Just CALL Create for one and Select
CALL CreateATable( 1 );
DESCRIBE aTable;
SELECT * FROM aTable;
CALL CreateATable( 2 );
DESCRIBE aTable;
SELECT * FROM aTable;
-- -> no errors
-- now CALL procedure to Create and Select from two different temp tables
CALL GetATable();
-- -> no errors
-- now CALL procedure to CREATE AND SELECT from ONE temp table definition using a parameter to select
CALL GetATable2(1);
CALL GetATable2(2);
-- Error Code: 1054. Unknown column 'mySchema.aTable.the_column' in 'field list'
I would expect that I can pass a parameter to a stored procedure to generate a temporary table, and return the records of that temporary table. Even if I call that same procedure multiple times with different parameters on the same session.
The actual results are that when the stored procedure is called to generate the temporary table with a different table structure, it returns this error complaining about the column missing from the temporary table created in the previous invocation of that same stored procedure.
Error Code: 1054. Unknown column 'mySchema.aTable.the_column' in 'field list'
The only way I have found to prevent this error is
a. ending the jdbc connection and ending the server session
b. recompiling one of the stored procedures in the call stack
Recompiling is not viable. And ending the session seems unreasonable.
This seems like a defect. But would be interested to find if there is some way to get this to work.
This seems like a bug and you can report it directly to the MariaDB team at MariaDB bugs database.
A temporary solution is to use a prepared statement in the stored procedure GetATable2 (my test on MariaDB 10.3.16 to use EXECUTE IMMEDIATE):
...
CREATE PROCEDURE `GetATable2`(`_TableType` TINYINT)
BEGIN
CALL CreateATable(`_TableType`);
-- SELECT * FROM `aTable`;
EXECUTE IMMEDIATE 'SELECT * FROM `aTable`';
END$$
...
See dbfiddle.

how can i call stored procedure from the function in mariadb?

i want to get count of no.of rows present in table which i pass at runtime to a function.
i have created a procedure and function to execute dynamic queries. function will not allow dynamic query because i am calling procedure from function.
that procedure having dynamic query.
///////procedure///////
CREATE PROCEDURE bizopsgolddev.`test1`(tbnm varchar(100))
begin
declare sql_text varchar(200);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT CONCAT(sql_text, ' is not valid');
END;
set sql_text=concat('select count(*) from ',tbnm);
SET #SQL := sql_text;
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
end;
//////function//////
DROP FUNCTION IF EXISTS xyz;
CREATE FUNCTION `xyz`(tname varchar(100)) RETURNS int(11)
begin
declare val int;
call test1(tname);
return 1;
end;
if i execute this //select xyz('axpdc')// it should return rows count
can any one tell me how can i get count by passing table name to function(in mariadb only)
As I understand the question, the solution would be a function that returns the row count of a table with it's name passed to the function as a parameter.
I think this could be done by querying the information_schema database in MariaDB. A function could look like this:
CREATE DEFINER = 'yourUsername'#'192.168.%'
FUNCTION testDataBase.fn_GetRowCount(tableName VARCHAR(128))
RETURNS int(11)
BEGIN
-- This could be a parameter if need it to be.
DECLARE databaseName varchar(40) DEFAULT 'testDataBase';
DECLARE result int DEFAULT -1;
SELECT t.TABLE_ROWS INTO result
FROM information_schema.TABLES t
WHERE t.TABLE_NAME = tableName
AND t.TABLE_SCHEMA = databaseName;
RETURN result;
END
In order for this to work the user mentioned as the definer must have read privilege to the TABLES table in the information_schema database, otherwise you might get an error (tbh, I don't know if this is necessary).
There is a lot of useful information to be grabbed from the information_schema database.

Unable to execute dynamic sql Error:global_names parameter must be set to TRUE for this operation

I have a remote table with blob column accessed via a db link. I want to insert a blob from my local table to remote table blob column.I am executing dynamic sql like follows
declare
theblob blob;
theclob clob;
thenumber number;
begin
select base64encode2(image) into theclob from per_images where image_id = 113077;
execute immediate 'insert into image#APPSERP2ERPAPPS(column1,column2,column3) values((select null from dual),(select base64encode2(image) from per_images where image_id = 113077),(select ceil(5.4) from dual))';
commit;
end;
When i run the sql i get ORA-02069: global_names parameter must be set to TRUE for this operation.
If i do ALTER SESSION SET GLOBAL_NAMES = true then i get database link APPSERP2ERPAPPS.CSN.EDU.PK connects to TEST.CSN.EDU.PK error while inserting into blob.
Kindly tell me how can i insert blob into remote table blob column.
Thanks
To be able to insert over a dblink the insert sentence must match this format
Insert into table2#dblink select * from Table1
here more info.

PlSql dynamic cursor Creation with input dynamic table name

Hi My PL/SQL function is
create or replace
PROCEDURE DiffrencesIdentifyerProc(db_nameFirst VARCHAR2,db_nameSecond VARCHAR2,table_name VARCHAR2) IS
dbremort varchar2(100):= db_nameFirst;
dblocal varchar2(100):= db_nameSecond;
tableName varchar2(100) := table_name;
CURSOR cur IS
SELECT * FROM s1.ENTITYFIELDS MINUS SELECT * FROM s2.ENTITYFIELDS;
BEGIN
FOR e IN cur
LOOP
dbms_output.put_line(e.ATTACH_NAME );
END LOOP;
END DiffrencesIdentifyerProc;
What I want is in
CURSOR cur IS
SELECT * FROM s1.ENTITYFIELDS MINUS SELECT * FROM s2.ENTITYFIELDS;
Select Part passed paramters to be setted like
SELECT * FROM dbremort.dbremort MINUS SELECT * FROM dbremort.dbremort ;
How can I do that???
Build/construct your query to a varchar2 (or clob when on Oracle 11g or newer) variable, then use native dynamic SQL's open for ... statement for opening the cursor and fetch statement for fetching from it.
Remember that you'll have to have a statically declared structure for fetching the data into from the cursor, anyway, so your dynamic queries will have to have identical number of selected columns with identical (or implicitly convertable) data types.

Best way to insert values multiple times from data layer to stored procedure?

Hi
I have DAL Layer, from where invoking a stored procedure to insert values into the table.
E.g.:-
CREATE PROCEDURE [dbo].[DataInsert]
#DataName nvarchar(64)
AS
BEGIN
INSERT INTO
table01 (dataname)
VALUES
(#dataname)
END
Now as requirement changed, per client request i have to add values 5 times. So what is the best practice?
Do i call this Stored Procedure 5 times from my DAL?
or
Pass all the values (may be comma separated) to storedprocedure in one go and then let the stored procedure add it for 5 times?
BTW. Its not always 5 times. It is changeable.
You could create a user-defined table type;
CREATE TYPE [dbo].[SomeInfo] AS TABLE(
[Id] [int] NOT NULL,
[SomeValue] [int] NOT NULL )
Define your stored proc as such;
CREATE PROCEDURE [dbo].[AddSomeStuff]
#theStuff [SomeInfo] READONLY
AS
BEGIN
INSERT INTO SOMETABLE ([...columns...])
SELECT [...columns...] from #theStuff
END
Then you'll need to create a datatable (called table below) that matches the schema and call the stored proc as so;
var cmd = new SqlCommand("AddSomeStuff", sqlConn) {CommandType = CommandType.StoredProcedure};
var param = new SqlParameter("#theStuff", SqlDbType.Structured) {Value = table};
cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();
btw this proc works - I've just written and tested it see results below!
CREATE PROCEDURE [dbo].[DataInsert]
#DataName nvarchar(max) AS
BEGIN
DECLARE #pos SMALLINT, #str VARCHAR(max)
WHILE #DataName <> ''
BEGIN
SET #pos = CHARINDEX(',', #DataName)
IF #pos>0
BEGIN
SET #str = LEFT(#DataName, #pos-1)
SET #DataName = RIGHT(#DataName, LEN(#DataName)-#pos)
END
ELSE
BEGIN
SET #str = #DataName
SET #DataName = ''
END
INSERT INTO table01 VALUES(CONVERT(VARCHAR(100),#str))
END
END
GO
then run it: -
EXEC #return_value = [dbo].[DataInsert]
#DataName = N'five, bits, of, your, data'
*rows from table01: *
five
bits
of
your
data
(5 row(s) affected)
I'd either call your proc repeatedly(that would be my choice), or else you could use XML to pass in a list of values as a single parameter.
http://support.microsoft.com/kb/555266
Instead of fancy SQL code that is difficult to maintain and is not scalable, I would simply go to invoking your stored procedure multiple times.
If performance or transactional behavior is an issue, you can consider to send the commands in a single batch.
You talked about 5 insert. If the number of record to insert is much greater, you could consider bulk insert as well.

Resources