#sql-server #tsql
#sql-сервер #tsql
Вопрос:
Я хочу выполнить 3 хранимые процедуры в WHILE
цикле. Итак, сначала я ищу данные, которые мне нужны как:
DECLARE @FBOMDesigns AS TABLE
(
DesignKey INT,
ParentDesignKey INT,
ProjectKey INT,
CurrentRow INT
)
INSERT INTO @FBOMDesigns
SELECT
D.DesignKey, [D].ParentDesignKey,
[PD].[ProjectKey],
ROW_NUMBER() OVER(ORDER BY D.[DesignKey]) AS [CurrentRow]
FROM
##Design AS D
INNER JOIN
##ProjectDesign AS PD ON D.DesignKey = PD.DesignKey
WHERE
DesignTypeGuid = '13B58AC4-F8BD-431F-8977-BE9C1FF25C7C'
DECLARE @NewCDDesigns AS TABLE
(
DesignKey INT,
CurrentRow INT
)
INSERT INTO @NewCDDesigns
SELECT
D.DesignKey,
ROW_NUMBER() OVER (ORDER BY D.DesignKey) AS CurrentRow
FROM
##Design AS D
INNER JOIN
##ProjectDesign AS PD ON D.DesignKey = PD.DesignKey
INNER JOIN
@FBOMDesigns as FD ON PD.ProjectKey = FD.ProjectKey
WHERE
PD.ProjectKey IN (SELECT ProjectKey FROM @FBOMDesigns)
AND D.DesignTypeGuid = '54FBBC23-CB9A-4311-9D7F-0DD7A774F33D'
AND D.Folio = 0
Как вы можете видеть, я создаю две таблицы с информацией
Как только у меня это есть, я устанавливаю переменные while:
DECLARE @counter INT = 1,
@max INT = 0,
@DesignKey INT
SET @max = (SELECT COUNT(DesignKey) FROM @NewCDDesigns)
Примечание: @max
значение равно 628
Таким образом, цикл должен пройти 628 раз:
WHILE @counter <= @max
BEGIN
DECLARE @CurrentDesignKey INT = (SELECT TOP 1 DesignKey FROM @NewCDDesigns
WHERE [CurrentRow] = @counter)
DECLARE @CurrentPreviousDesignKey INT = (SELECT TOP 1 DesignKey FROM @FBOMDesigns
WHERE ParentDesignKey = (SELECT TOP 1 DesignKey FROM @NewCDDesigns WHERE [CurrentRow] = @counter))
EXEC [copyPreviousDesign]
@DesignKey = @CurrentDesignKey ,
@PreviousDesignKey = @CurrentPreviousDesignKey
EXEC [copyCustomersFromPreviousDesign]
@DesignKey =@CurrentDesignKey ,
@PreviousDesignKey = @CurrentPreviousDesignKey
EXEC [addDefaultTasksToDesign]
@DesignKey = @CurrentDesignKey
END
Проблема в том, что запрос занял слишком много времени, SQL Server Management Studio застрял на 29 минуте, и мне нужно принудительно закрыть. Есть ли какой-нибудь способ сделать это быстрее?
Комментарии:
1. «Есть ли какой-нибудь способ сделать это быстрее?» Да, не используйте
WHILE
цикл. SQL Server предназначен для операций на основе наборов, а не интерактивных, поэтому он хорошо выполняет первое и плохо — второе. Если вы можете объяснить, какова ваша фактическая цель здесь, мы можем помочь вам превратить то, что у вас есть, в процесс, основанный на наборе.2. У вас также есть top 1 без order by. Не имеет значения, какую строку вы получите?
Ответ №1:
Вы должны увеличить @counter внутри цикла while. Это бесконечный цикл.
выберите @counter = @counter 1;
Комментарии:
1. Хотя это решение проблемы, оно лишь указывает на то, что использование цикла здесь является плохим способом обработки данных.