Извлечение значений из временной таблицы после итерации - PullRequest
1 голос
/ 06 июня 2019

Я запрашиваю общий размер последних данных в определенных базах данных.

Я создаю таблицу, содержащую запрашиваемые БД, затем выполняю итерацию по ней, чтобы получить имена БД и общее количество раз для запускаитерация.

Затем я создаю шаблон, в который будут вставлены необходимые данные.

Я запускаю итерацию, чтобы получить информацию и вставить ее в шаблон для каждой базы данных.

После завершения итерации я не могу получить значения из этой вновь созданной таблицы.

Я написал небольшой комментарий рядом с каждой частью кода, объясняющий, что я пытаюсь сделать и чего я ожидаю.

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

Когда этот последний оператор select выполняется для извлечения значений из #temptable, ответ представляет собой один столбец Gigs (как и ожидалось), но сама таблица пуста.

Что-то происходит, чтобы удалить данные из таблицы, и я застрял.

Я не уверен, что моя ошибка в синтаксисе или общая ошибка логики, но любая помощь могла быс благодарностью.

Ответы [ 2 ]

2 голосов
/ 06 июня 2019

Это второй ответ, но его альтернатива аналогична той, что я упоминал выше, и более чистая публикация для публикации в качестве альтернативного ответа, чтобы держать их отдельно

Это лучший способ зацикливания (еще не полностью протестирован, поэтому вам придется проверить).

Но вместо удаления из таблицы просто добавьте в нее идентификатор и выполните цикл с использованием этого идентификатора. Намного меньше шагов и намного чище.

--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
2 голосов
/ 06 июня 2019

Внесены некоторые изменения в форматирование, но основная проблема заключается в том, что ваш цикл никогда не запустится.

У вас есть @runs <= @max, но @max = 1 и @runs = 0 при запуске, поэтому он никогда не будетloop </p>

Чтобы исправить это, вы можете сделать несколько разных вещей, но я установил @max перед циклом, а в цикле просто добавил 1 в @runs для каждого цикла, так как вы знаете, сколько вам нужно @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...