Resolving data redundancy up front

Posted by okeofs on SQL Blogcasts See other posts from SQL Blogcasts or by okeofs
Published on Mon, 22 Apr 2013 17:58:00 GMT Indexed on 2013/06/24 16:30 UTC
Read the original article Hit count: 281

Filed under:

Introduction

As all of us do when confronted with a problem, the resource of choice is to ‘Google it’.

This is where the plot thickens. Recently I was asked to stage data from numerous databases which were to be loaded into a data warehouse. To make a long story short, I was looking for a manner in which to obtain the table names from each database, to ascertain potential overlap.

 

As the source data comes from a SQL database created from dumps of a third party product,  one could say that there were +/- 95 tables for each database.

 

Yes I know that first instinct is to use the system stored procedure “exec sp_msforeachdb 'select "?" AS db, * from [?].sys.tables'”.

However, if one stops to think about this, it would be nice to have all the results in a temporary or disc based  table; which in itself , implies additional labour.

This said,  I decided to ‘re-invent’ the wheel. The full code sample may be found at the bottom of this article.

 

Define a few temporary tables and variables

 

declare @SQL varchar(max);

declare @databasename varchar(75)

/*

drop table ##rawdata3

drop table #rawdata1

drop table #rawdata11

*/

-- A temp table to hold the names of my databases

CREATE TABLE #rawdata1

(

   database_name varchar(50) ,

   database_size varchar(50),

   remarks Varchar(50)

)

 

 

--A temp table with the same database names as above, HOWEVER using an

--Identity number (recNO) as a loop variable.

--You will note below that I loop through until I reach 25 (see below) as at

--that point the system databases, the reporting server database etc begin.

--1- 24 are user databases. These are really what I was looking for.

--Whilst NOT the best solution,it works and the code was meant as a quick

--and dirty.

CREATE TABLE #rawdata11

(

   recNo int identity(1,1),

   database_name varchar(50) ,

   database_size varchar(50),

   remarks Varchar(50)

)

 

--My output table showing the database name and table name

CREATE TABLE ##rawdata3

(

   database_name varchar(75) ,

   table_name varchar(75),

)

 

Insert the database names into a temporary table

I pull the database names using the system stored procedure sp_databases

 

INSERT INTO #rawdata1

EXEC sp_databases

Go

 

Insert the results from #rawdata1 into a table containing a record number  #rawdata11 so that I can LOOP through the extract

 

INSERT into #rawdata11

select * from  #rawdata1

 

We now declare 3 more variables:

 @kounter is used to keep track of our position within the loop.

@databasename is used to keep track of the’ current ‘ database name being used in the current pass of the loop;  as inorder to obtain the tables for that database we  need to issue a ‘USE’ statement, an insert command and other related code parts. This is the challenging part.

@sql is a varchar(max) variable used to contain the ‘USE’ statement PLUS the’ insert ‘ code statements.

We now initalize @kounter to 1 .

 

declare @kounter int;

declare @databasename varchar(75);

declare @sql varchar(max);

set @kounter = 1

 

The Loop

The astute reader will remember that the temporary table #rawdata11 contains our  database names  and each ‘database row’ has a record number (recNo). I am only interested in record numbers under 25. I now set the value of the temporary variable @DatabaseName (see below) .Note that I used the row number as a part of the predicate.

Now, knowing the database name, I can create dynamic T-SQL to be executed using the sp_sqlexec stored procedure (see the code in red below).

Finally, after all the tables for that given database have been placed in temporary table ##rawdata3, I increment the counter and continue on.

Note that I used a global temporary table to ensure that the result set persists after the termination of the run.

At some stage, I plan to redo this part of the code, as global temporary tables are not really an ideal solution.


 

 WHILE (@kounter < 25)

 BEGIN

 select @DatabaseName = database_name from #rawdata11 where recNo = @kounter

 set @SQL = 'Use ' + @DatabaseName +

' Insert into ##rawdata3 ' +

+ ' SELECT table_catalog,Table_name FROM information_schema.tables'

exec sp_sqlexec  @Sql

 SET @kounter  = @kounter + 1

 END

 

The full code extract

 

Here is the full code sample.

 

declare @SQL varchar(max);

declare @databasename varchar(75)

/*

drop table ##rawdata3

drop table #rawdata1

drop table #rawdata11

*/

CREATE TABLE #rawdata1

(

   database_name varchar(50) ,

   database_size varchar(50),

   remarks Varchar(50)

)

CREATE TABLE #rawdata11

(

   recNo int identity(1,1),

   database_name varchar(50) ,

   database_size varchar(50),

   remarks Varchar(50)

)

CREATE TABLE ##rawdata3

(

   database_name varchar(75) ,

   table_name varchar(75),

)

 

INSERT INTO #rawdata1

EXEC sp_databases

go

INSERT into #rawdata11

select * from  #rawdata1

declare @kounter int;

declare @databasename varchar(75);

declare @sql varchar(max);

set @kounter = 1

WHILE (@kounter < 25)

 BEGIN

 select @databasename = database_name from #rawdata11 where recNo = @kounter

 set @SQL = 'Use ' + @DatabaseName +

' Insert into ##rawdata3 ' +

+ ' SELECT table_catalog,Table_name FROM information_schema.tables'

exec sp_sqlexec  @Sql

 SET @kounter  = @kounter + 1

 END

 

 select * from ##rawdata3

 where table_name like '%SalesOrderHeader%'

© SQL Blogcasts or respective owner