Wednesday, April 5, 2017

Execute a query for all tables and fill in data in new one

Leave a Comment

I need to get the result table with there fields - table_name, min_date, max_date

Here is my query, which I should execute for all tables

SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate FROM (SELECT  short_date, type, value,  count(*) as cnt FROM testTable GROUP BY  short_date HAVING COUNT(*) > 1) as Duplicates 

Then I found out how to get all table names I do it in this way

SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` WHERE `TABLES`.`TABLE_SCHEMA` = 'test' AND `TABLES`.`TABLE_NAME` LIKE 'test%' 

But I don't know how to execute it for all table and fill in the result in a new table.

I tried to do it in this way

DECLARE @DB_Name varchar(50) DECLARE @Command varchar(100); DECLARE database_cursor CURSOR FOR  SELECT name  FROM (SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` WHERE `TABLES`.`TABLE_SCHEMA` = 'test' AND `TABLES`.`TABLE_NAME` LIKE 'test%') as TableNames  OPEN database_cursor  FETCH NEXT FROM database_cursor INTO @DB_Name  WHILE @@FETCH_STATUS = 0  BEGIN       SELECT @Command = 'SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate FROM (SELECT  short_date, type, value,  count(*) as cnt FROM ' + @DB_Name + ' WHERE type = ''test'' GROUP BY  short_date, type, value HAVING COUNT(*) > 1) as Duplicates'      EXEC sp_executesql @Command       FETCH NEXT FROM database_cursor INTO @DB_Name  END  CLOSE database_cursor  DEALLOCATE database_cursor 

But I got this error

Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE @DB_Name varchar(50) DECLARE @Command varchar(100)' at line 1

UPD

CREATE PROCEDURE GetData() BEGIN  DECLARE @DB_Name varchar(50), @Command varchar(100); DECLARE database_cursor CURSOR FOR  SELECT name  FROM (SELECT TABLE_NAME as name FROM `information_schema`.`TABLES` WHERE `TABLES`.`TABLE_SCHEMA` = 'test' AND `TABLES`.`TABLE_NAME` LIKE 'test%_') as TableNames  OPEN database_cursor  FETCH NEXT FROM database_cursor INTO @DB_Name  WHILE @@FETCH_STATUS = 0  BEGIN       SELECT @Command = 'SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate FROM (SELECT  short_date, type, value,  count(*) as cnt FROM ' + @DB_Name + ' WHERE type = ''test'' GROUP BY  short_date, type, value HAVING COUNT(*) > 1) as Duplicates'      EXEC sp_executesql @Command       FETCH NEXT FROM database_cursor INTO @DB_Name  END;  CLOSE database_cursor  DEALLOCATE database_cursor  END;  CALL GetData() 

3 Answers

Answers 1

Add DELIMITER $$ at the start; add DELIMITER ; after END.

Get rid of declaring Command. Instead use @command, which does not need to be declared.

Add SELECT @command; after the SELECT @command := ...; so that we can do some debugging.

The CLOSE and DEALLOCATE statements need ; to terminate them.

Test for running out of rows to FETCH.

You really need to look at a number of examples of Stored procedures, especially those with cursors.

Update

Ugh, I did not spot even half the syntax errors. This might work (I can't tell because I don't have your particular tables or columns.):

DROP PROCEDURE IF EXISTS so42856538;  DELIMITER $$  CREATE PROCEDURE so42856538()     LANGUAGE SQL     MODIFIES SQL DATA     SQL SECURITY INVOKER BEGIN  DECLARE _TableName varchar(64); DECLARE _done INT DEFAULT FALSE; DECLARE database_cursor CURSOR FOR      SELECT TABLE_NAME         FROM `information_schema`.`TABLES`         WHERE `TABLE_SCHEMA` = 'test'           AND `TABLE_NAME` LIKE 'test%'; DECLARE CONTINUE HANDLER FOR NOT FOUND SET _done = TRUE;  OPEN database_cursor; curs_loop: LOOP     FETCH NEXT FROM database_cursor INTO _TableName;     IF _done THEN  LEAVE curs_loop;  END IF;     SET @Command := CONCAT(            'SELECT MIN(short_date) as FirstDuplicatedDate,                            MAX(short_date) as LastDuplicatedDate            FROM ( SELECT  short_date, type, value,  count(*) as cnt                     FROM ', _TableName, '                     WHERE type = "test"                     GROUP BY  short_date, type, value                     HAVING COUNT(*) > 1 ) as Duplicates'                         );     SELECT _TableName, @command;   -- Debugging (remove if it is clutter)     PREPARE _sql FROM @command;     EXECUTE _sql;     DEALLOCATE PREPARE _sql; END LOOP; CLOSE database_cursor;  END $$  DELIMITER ;  CALL so42856538; 

Answers 2

right... you might want to try this.

remove this line and run the query again.

DECLARE @DB_Name varchar(50), @Command varchar(100); 

i think in mysql you can just use a variable without declaring it and then cast when necessary.

Answers 3

As far as my knowledge concern this error is due to ,DELIMETER and one more thing that you have to apply cursor properly to iterate whole rowset.Here in below code i had wrote down procedure with CURSOR.Make dynamic query and execute that dynamic query using

PREPARE stmt FROM @VAR_QRY; EXECUTE stmt; 

That dynamic query will returns exact output you want.Here i had assuming that you have basic knowledge about trigger,loop and Cursor

Try below code. Hope this will helps.

DROP PROCEDURE IF EXISTS ITERATEALLTABLE; DELIMITER $$ CREATE PROCEDURE ITERATEALLTABLE() BEGIN DECLARE VAR_TABLE varchar(100); DECLARE VAR_QRY varchar(100); DECLARE VAR_FINISHED INT(11) DEFAULT 0; DECLARE DATABASE_CURSOR CURSOR FOR                  SELECT name AS TableNames                 FROM (                     SELECT TABLE_NAME as name FROM `information_schema`.`TABLES`                     WHERE `TABLES`.`TABLE_SCHEMA` = 'test'                     AND `TABLES`.`TABLE_NAME` LIKE 'test%'                 )Z ;                   DECLARE CONTINUE HANDLER FOR NOT FOUND SET VAR_FINISHED = 1;                  OPEN DATABASE_CURSOR;                 GET_NEXTRECORD: LOOP                          FETCH DATABASE_CURSOR INTO VAR_TABLE;                              IF VAR_FINISHED = 1 THEN                              LEAVE GET_NEXTRECORD;                             END IF;                              SET @VAR_QRY = CONCAT("SELECT MIN(short_date) as FirstDuplicatedDate, MAX(short_date) as LastDuplicatedDate                             FROM (SELECT  short_date, type, value,  count(*) as cnt                             FROM " , VAR_TABLE , " WHERE type = 'test'                             GROUP BY  short_date, type, value                             HAVING COUNT(*) > 1) as Duplicates");                              PREPARE stmt FROM @VAR_QRY;                             EXECUTE stmt;                  END LOOP GET_NEXTRECORD;                  CLOSE DATABASE_CURSOR;  END;  CALL ITERATEALLTABLE; 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment