迭代后从临时表中提取值

时间:2019-06-06 17:16:43

标签: sql-server tsql iteration temp-tables sql-server-2017

我正在查询某些数据库中最近数据的总大小。

我创建了一个表,其中包含要查询的数据库,然后对其进行迭代以获取数据库名称和运行迭代的总次数。

然后我创建一个临时表,将所需的数据插入其中。

我运行迭代以获取信息并将其推入每个数据库的临时表中。

迭代完成后,我无法从此新创建的表中提取值。

我在代码的每个部分旁边写了一个小注释,解释了我正在尝试做的事情以及我期望发生的事情。

margin-right

当该最终选择语句运行以从#temptable中提取值时,响应为单个gigs列(如预期的那样),但表本身为空白。

正在清除表中的数据,我被卡住了。

我不确定我的错误是语法还是逻辑上的一般错误,但是任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

对格式进行了一些调整,但主要问题是循环永远不会运行。

您有@runs <= @max,但是@max = 1且@runs = 0,因此它永远不会循环

要解决此问题,您可以做几件事,但是我设置了@max before循环,并且在循环中,每个循环只向@runs加了1,因为您知道在循环运行之前需要@max多少,将其添加到运行次数中,然后进行比较。

但是请注意,有比您拥有的方法更好的方法。将身份放在您的#databases表上,然后在循环中执行databaseID = loopCount(然后不必从表中删除)

--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

答案 1 :(得分:2)

这是第二个答案,但是它类似于我在上面提到的那样,并且更清洁地发布以作为使它们分开的另一个答案

这是进行循环的更好方法(尚未经过全面测试,因此您必须进行验证)。

但是,除了从表中删除之外,只需向其添加一个ID并使用该ID遍历即可。减少步骤,更清洁。

--check if the #databases table is already present and then drop it
IF OBJECT_ID('tempdb..#databases', 'U') IS NOT NULL
    drop table #databases;


--create the temp table as outside the loop
create table #databases(
    ID INT IDENTITY,
    ArtifactID VARCHAR(20) -- not sure of this ID's data type
)


--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
)

--this will allow the population of each database name
DECLARE @databasename sysname = '' 

-- initialze to 1 so it matches first record in temp table
DECLARE @LoopOn int = 1; 

--this will be the max  count from table
DECLARE @MaxCount int = 0; 

--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]

-- do insert here so it adds the ID column
INSERT INTO #databases(
    ArtifactID
)
SELECT ArtifactID 
FROM edds.eddsdbo.[Case]
where name like '%Review%'

-- sets the max number of loops we are going to do
select @MaxCount = COUNT(*) 
FROM #databases;

while @LoopOn <= @MaxCount
    BEGIN
        -- your table has IDENTITY so select the one for the loop your on (initalize to 1)
        select @databasename = ArtifactID 
        FROM #databases
        WHERE ID = @LoopOn;

        --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
        -- dont know/think this will work like this?  If not you have to use dynamic SQL 
        FROM [EDDS'+cast(@databasename as nvarchar(128))+'].[EDDSDBO].[Document] ed
        where ed.CreatedDate >= (select CONVERT(varchar,dateadd(d,- (day(getdate())),getdate()),106))

        -- remove all deletes/etc and just add one to the @LoopOn and it will be selected above based off the ID
        select @LoopOn += 1
end

-- Query the final values in the temp table after the iteration is complete
select filesize+extractedTextSize as Gigs 
FROM #temptable