Search code examples
sql-servert-sqliterationtemp-tablessql-server-2017

Pulling Values From Temp Table After An Iteration


I'm querying for the total sizes of recent data in certain databases.

I create a table containing the DBs to be queried then iterate over it to get the DB names and total number of times to run the iteration.

I then create a temptable where the needed data will be inserted into.

I run the iteration to grab the information and push it into the temptable for each database.

After the iteration finishes I'm not able to pull the values from this newly created table.

I wrote a little comment next to each portion of code explaining what I'm trying to do and what I expect to happen.

/*check if the #databases table is already present and then drop it*/

IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
begin
    drop table #databases;
end

select ArtifactID into #databases from edds.eddsdbo.[Case]
where name like '%Review%'

/*Once this first statement has been run there will now be a
number column that is associated with the artificatID. Each database has an area that is 
titled [EDDS'artifactID']. So if the artifactID = 1111111 then the DB would 
be accessed at [EDDS1111111]*/

declare @runs int = 1; /*this will track the number of times iterated 
over the result set*/

declare @max int = 0; /*this will be the limit*/

declare @databasename sysname='' /*this will allow the population of each 
database name*/

/*check if your temp table exists and drop if necessary*/
IF OBJECT_ID('tempdb..#temptable', 'U') IS NOT NULL
begin
    drop table #temptable;
end

/*create the temp table as outside the loop*/

create table #temptable(
fileSize dec,
extractedTextSize dec
)


while @runs<=@max
begin

select @max=count(*) from #databases;
/*the @max is now the number of databases inserted in to this table*/


/*This select statement pulls the information that will be placed 
into the temptable. This second statment should be inside the loop. One time 
for each DB that appeared in the first query's results.*/

/*begin the loop by assigning your database name, I don't know what the 
column is called so I have just called it databasename for now*/

select top 1 @databasename = ArtifactID from #databases;

/*generate your sql using the @databasename variable, if you want to make 
the database and table names dynamic too then you can use the same formula*/

insert into #temptable
select SUM(fileSize)/1024/1024/1024, SUM(extractedTextSize)/1024/1024
FROM [EDDS'+cast(@databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,- 
(day(getdate())),getdate()),106))'


/*remove that row from the databases table so the row won't be redone
This will take the @max and lessen it by one*/
delete from #databases where ArtifactID=@databasename;

/* Once the @max is less than 1 then end the loop*/
end

/* Query the final values in the temp table after the iteration is complete*/
select filesize+extractedTextSize as Gigs from #temptable

When that final select statement runs to pull values from #temptable the response is a single gigs column(as expected) but the table itself is blank.

Something is happening to clear the data out of the table and I'm stuck.

I'm not sure if my error is in syntax or a general error of logic but any help would be greatly appreciated.


Solution

  • Made a few tweaks to formatting but main issue is your loop would never run.

    You have @runs <= @max, but @max = 1 and @runs = 0 at start so it will never loop

    To fix this you can do a couple different things but I set the @max before loop, and in the loop just added 1 to @runs each loop, since you know how many you need @max before loop runs, and just add it to number of runs and do your compare.

    But one NOTE there are much better ways to do this then the way you have. Put identity on your #databases table, and in your loop just do where databaseID = loopCount (then you dont have to delete from the table)

    --check if the #databases table is already present and then drop it
    IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
        drop table #databases;
    
    
    --Once this first statement has been run there will now be a number column that is associated with the artificatID. Each database has an area that is 
    --      titled [EDDS'artifactID']. So if the artifactID = 1111111 then the DB would be accessed at [EDDS1111111]
    select ArtifactID 
    INTO #databases 
    FROM edds.eddsdbo.[Case]
    where name like '%Review%'
    
    
    -- set to 0 to start 
    DECLARE @runs int = 0; 
    
    --this will be the limit
    DECLARE @max int = 0; 
    
    --this will allow the population of each database name
    DECLARE @databasename sysname = '' 
    
    --check if your temp table exists and drop if necessary
    IF OBJECT_ID('tempdb..#temptable', 'U') IS NOT NULL
        drop table #temptable;
    
    --create the temp table as outside the loop
    create table #temptable(
        fileSize dec,
        extractedTextSize dec
    )
    
    -- ***********************************************
    --  Need to set the value your looping on before you get to your loop, also so if you dont have any you wont do your loop
    -- ***********************************************      
    --the @max is now the number of databases inserted in to this table
    select @max = COUNT(*) 
    FROM #databases;
    
    while @runs <= @max  
        BEGIN
    
            /*This select statement pulls the information that will be placed 
            into the temptable. This second statment should be inside the loop. One time 
            for each DB that appeared in the first query's results.*/
    
            /*begin the loop by assigning your database name, I don't know what the 
            column is called so I have just called it databasename for now*/
    
            select top 1 @databasename = ArtifactID from #databases;
    
            /*generate your sql using the @databasename variable, if you want to make 
            the database and table names dynamic too then you can use the same formula*/
    
            insert into #temptable
            select SUM(fileSize)/1024/1024/1024, SUM(extractedTextSize)/1024/1024
            FROM [EDDS'+cast(@databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
            where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,- (day(getdate())),getdate()),106))
    
    
            --remove that row from the databases table so the row won't be redone This will take the @max and lessen it by one
            delete from #databases where ArtifactID=@databasename;
    
            --Once the @max is less than 1 then end the loop
    
            -- ***********************************************
            -- no need to select from the table and change your max value, just change your runs by adding one for each run
            -- ***********************************************      
            --the @max is now the number of databases inserted in to this table
            select @runs = @runs + 1  --@max=count(*) from #databases;
    
    
    end
    
    -- Query the final values in the temp table after the iteration is complete
    select filesize+extractedTextSize as Gigs from #temptable