1

I've been googling to find an answer but can't find anything. I have a cursor statement that pulls the name of the tables that are present in the database.

THe goal is: a stored procedure with 2 parameters, database1 and database2 comparing both databases and outputting the difference. database names are tab/space delimited

BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE db_tables VARCHAR(256);

DECLARE cursor1 CURSOR FOR 
        SELECT TABLE_NAME, TABLE_SCHEMA
        FROM information_schema.tables  
        WHERE TABLE_SCHEMA = db1
        AND TABLE_TYPE = 'BASE TABLE';

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cursor1;
FETCH cursor1 into db_tables;

WHILE done = FALSE DO
SET query1 = SELECT * FROM db1 WHERE table1 IN(table_name);
END WHILE;
CLOSE cursor1;

END
Jim
  • 27
  • 1
  • 6
  • you just gave us a spec asking us to write it, ya know – Drew Sep 16 '15 at 18:01
  • oh sorry didnt mean that, I have some code worked up and input it here @drew . I Just need some direction and some ideas how to tackle this. KInd of lost. – Jim Sep 16 '15 at 18:57
  • @barmar sorry , it's very raw , that's why I didnt place it but I updated post with code. – Jim Sep 16 '15 at 18:59
  • sounds good. show us two schemas. And the expected output now. So we know what `outputting the difference` means – Drew Sep 16 '15 at 19:03
  • So, pretty much I want to compare a list of tables and spit out the difference. By difference I mean it checks if the tables are present in the other table. Spits out what is not found. If database1 has no matches with database 2 all the tables would be spit out. If it has 3 out of 3 matching tables it would not spit out any result. @Drew – Jim Sep 18 '15 at 18:20
  • so just table name differences. Differences in the existence of tables. 1 column per row – Drew Sep 18 '15 at 18:38
  • Yes, just comparing the tables by name, whether present or not @drew – Jim Sep 18 '15 at 18:40
  • that's rather easy. give me a bit. eating some sugar – Drew Sep 18 '15 at 18:42
  • Really? I'm just having a hard time pulling the other database, would I have to create another cursor for the 2nd database? – Jim Sep 18 '15 at 18:52

1 Answers1

0

This uses the INFORMATION_SCHEMA.TABLES information

The Schema

create database db1;
create database db2;

create table db1.s1 (id int);
create table db1.s2 (id int);
create table db1.s3 (id int);

create table db2.s2 (id int);
create table db2.s3 (id int);
create table db2.s4 (id int);

The Query

select t1.table_name, 2 as 'not in this one'
from INFORMATION_SCHEMA.TABLES t1
where t1.table_schema='db1'
and not exists (select * from INFORMATION_SCHEMA.TABLES t2 where t2.table_schema='db2' and t2.table_name=t1.table_name)
union
select t1.table_name, 1 as 'not in this one'
from INFORMATION_SCHEMA.TABLES t1
where t1.table_schema='db2'
and not exists (select * from INFORMATION_SCHEMA.TABLES t2 where t2.table_schema='db1' and t2.table_name=t1.table_name)

The Results

+------------+-----------------+
| table_name | not in this one |
+------------+-----------------+
| s1         |               2 |
| s4         |               1 |
+------------+-----------------+

This means that table s1 is in database db1, but not in db2, and that table s4 is in the database db2, but not in db1.

Stored Proc

delimiter $$
create procedure showDBDiffInTableNames
( x1 varchar(40),x2 varchar(40) )
BEGIN
    -- 
    -- passed parameters, x1 is a string containing the name of a database
    -- x2 is a string containing the name of another database
    --
    select t1.table_name, 2 as 'not in this one'
    from INFORMATION_SCHEMA.TABLES t1
    where t1.table_schema=x1
    and not exists (select * from INFORMATION_SCHEMA.TABLES t2 where t2.table_schema=x2 and t2.table_name=t1.table_name)
    union
    select t1.table_name, 1 as 'not in this one'
    from INFORMATION_SCHEMA.TABLES t1
    where t1.table_schema=x2
    and not exists (select * from INFORMATION_SCHEMA.TABLES t2 where t2.table_schema=x1 and t2.table_name=t1.table_name);
END
$$
DELIMITER ;

Test it:

call showDBDiffInTableNames('x1','x2');

same results

t1 and t2 are just table aliases. See the manual page here. From the manual page:

The following list describes general factors to take into account when writing joins.

A table reference can be aliased using tbl_name AS alias_name or tbl_name alias_name:

....

I almost never write a query without an alias if, knowing ahead of time, I am going after two or more tables. It cuts down on the typing. They are especially common in self-joins (to the same table). You need a way to differentiate which one you are dealing with to remove Ambiguous errors from queries. So that is why that alias is in there. Plus, you will note that the table is gone after twice.

There are two ways you can write it, as seen in the pink/peach block above.

Drew
  • 24,851
  • 10
  • 43
  • 78
  • Oh wow, you did this quick, yea I'll try to see if I can translate this into a stored procedure. So, using cursors is not a good idea? – Jim Sep 18 '15 at 19:28
  • i did an s.p. at the bottom. do a refresh – Drew Sep 18 '15 at 19:29
  • holy moly thanks so much, one question if you dont mind. The T1, is it a variable? Not sure where that came from. E.g, "from INFORMATION_SCHEMA.TABLES t1" . That line confuses me a lot. – Jim Sep 18 '15 at 20:50
  • my pleasure. `t1` is a table `alias`. Modified the bottom of the answer. It is because I am lazy that I don't use the phrase `as t1` or `as t2`, sorry about that. Good luck – Drew Sep 18 '15 at 21:11
  • Thanks gotcha! This has been very helpful! You're the man. @drew – Jim Sep 22 '15 at 02:25
  • So, just a question out of curiosity, what if I want to look at one database and check if the tables are present but the tables to be checked are stated by the user. For example, storeProc('databaseToCheck', 'table1 table2 table20'). So it checks to see if the tables the user input are present? @drew – Jim Sep 23 '15 at 16:06
  • `select 1 from table1`. Result set if it is there. Error 1146 if it is not. You could craft a stored proc and return a yay or nay off a list, sure. If yay or nay is not what you are looking for, then a list of the ones that are *not* there can be achieved. Or a 2 column result set of the names passed along with 1 or 0 (isItThere). Whatever you want – Drew Sep 23 '15 at 16:13
  • The problem I am encountering is that 'table1 table2 table20' is all being read as one string. So my variable for the parameter is 'tables VARCHAR(256)' . My issue is being able to pull each table the user specifies and using each one separately. I want to pull each one and check each one if present in the database the user specifies. I'm thinking of a loop, not too sure. @drew – Jim Sep 23 '15 at 16:23
  • I wrote a bizarre write-up yesterday [here](http://stackoverflow.com/a/32720846). Check near the bottom bold section where it says **Test (call the stored procedure)**. In that write-up it is a sentence with words separated with spaces (what else would it be :). Keep in mind that was just a funny goofy Question, we all knew it going in. Use PHP (whatever) not that crazy thing – Drew Sep 23 '15 at 16:29
  • Nice, let me take a look at it, from what it looks like it does look like something I'm trying to do :) thanks man. Also, how did you learn all this? lol do you have still have any resources you used when beginning? @drew – Jim Sep 23 '15 at 16:41
  • no smarter than anyone else here Jim. Just tinker. btw you don't need to at drew me at the end of messages if it is under my Answer :> I still get the msg – Drew Sep 23 '15 at 16:43