2016-08-19 5 views
1

Моя задача - автоматизировать некоторые действия (удаление старых строк из БД), которые теперь выполняются вручную. В настоящее время у меня есть два сценария MSSQL. Первый выбирает идентификаторы, с которыми мне нужно работать, а также количество строк для удаления для каждого идентификатора. И, похоже, что:Как слить два SQL-скрипта?

SELECT e.batchId, b.Name, count (*) "Count" 
FROM dbo.[Logs] e 
join [dbo.[Batch] b on b.Id = e.batchId 
Group by e.batchId, b.Name 
Having count(*) > 500 
order by [Count] 

Итак, после того, как я получаю все идентификаторы я должен работать, я запускаю второй один сценарий для каждого ID (изменяя его количество в сценарии вручную и relunching его для каждой строки от первого выбора):

Declare @counter INT 
Declare @fdel INT 
Declare @csize INT 
Declare @batchId INT 

select @batchId=666777 --HERE IS AN ID I CHANGE MANUALLY AND RELAUNCH THE SECOND ONE SCRIPT FOR IT 
select @csize=500 
select @counter = 0 
select @fdel=count(*) from dbo.Logs where batchId = @batchId 

While (@counter < @fdel) 
BEGIN 
select @counter = @counter + @csize 
BEGIN TRAN 
DELETE top(@csize) from dbo.Logs where batchId = @batchId 
COMMIT TRAN 
END 

Итак, как эти сценарии будут объединены в один, чтобы запустить весь сценарий только один раз?

ответ

1

Вы почти завершили CURSOR декларацию. Без обсуждения самого решения ваш код с «объединенными» запросами будет выглядеть так:

/* your declared variables and cursor variable */ 
DECLARE 
    @crBatches CURSOR, 
    @counter INT, 
    @fdel INT, 
    @csize INT = 500, 
    @batchId INT 

/* your first query declared as cursor/source for looping through batch_ids */ 
SET @crBatches = CURSOR FAST_FORWARD FOR 
SELECT e.batchId, count (*) "Count" 
FROM dbo.[Logs] e 
join [dbo.[Batch] b on b.Id = e.batchId 
Group by e.batchId, b.Name 
Having count(*) > 500 
order by [Count] 

OPEN @crBatches 

FETCH NEXT FROM @crBatches 
INTO @batchId, @fdel 

/* loop on batch_ids obtained from cursor */ 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @counter = 0 

    /* internal loop - your second query */ 
    While (@counter < @fdel) 
    BEGIN 
     SET @counter = @counter + @csize 

     BEGIN TRAN 
     DELETE top(@csize) from dbo.Logs where batchId = @batchId 
     COMMIT TRAN 
    END 

    FETCH NEXT FROM @crBatches 
    INTO @batchId, @fdel 
END 

CLOSE @crBatches 
DEALLOCATE @crBatches 
1

Вы можете использовать подзапрос и где в

delete from dbo.Logs 
where id in ( select id_to_del from 
    (SELECT e.batchId as id_to_del, b.Name, count (*) "Count" 
     FROM dbo.[Logs] e 
     join [dbo.[Batch] b on b.Id = e.batchId 
     Group by e.batchId, b.Name 
     Having count(*) > 500 
     order by [Count])); 
Смежные вопросы