spróbuj nigdy pętla, praca na zbiorach danych.
można wstawiać, aktualizować, usuwać wiele wierszy jednocześnie. tutaj w przykładowej wstawce wielu wierszy:
INSERT INTO YourTable
(col1, col2, col3, col4)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
Patrząc na pętlę, zobacz, co w niej zrobiono. Jeśli jest to tylko wstawianie/usuwanie/aktualizowanie, przepisz ponownie, aby użyć pojedynczych poleceń. Jeśli istnieją IFs, sprawdź, czy mogą to być instrukcje CASE lub warunki WHERE dotyczące wstawiania/usuwania/aktualizacji. Jeśli tak, usuń pętlę i użyj poleceń set.
Pobrałem pętle i zastąpiłem je komendami opartymi na zestawie i skróciłem czas wykonywania z minut do kilku sekund. Zrobiłem procedury z wieloma zagnieżdżonymi pętlami i wywołaniami procedur i utrzymywałem pętle (nie było możliwe używanie tylko wstawek/usunięć/aktualizacji), ale usunąłem kursor i widziałem mniej blokowania/blokowania i potężne zwiększenie wydajności, jak również. Oto dwa sposoby wykorzystaniem pętli, które są lepsze niż pętle kursor ...
jeśli masz do pętli na zbiorze zrobić coś takiego:
--this looks up each row for every iteration
DECLARE @msg VARCHAR(250)
DECLARE @hostname sysname
--first select of currsor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
WHILE @hostname is not null
BEGIN
set @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(@hostname) + ' '
+ 'testing "'
print @msg
--EXEC (@msg)
--next select of cursor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
and hostname > @hostname
END
jeśli masz rozsądny zestaw elementów (nie 100,000), aby wykonać pętlę, można to zrobić:
--this will capture each Key to loop over
DECLARE @msg VARCHAR(250)
DECLARE @From int
DECLARE @To int
CREATE TABLE #Rows
(
RowID int not null primary key identity(1,1)
,hostname varchar(100)
)
INSERT INTO #Rows
SELECT DISTINCT hostname
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
SELECT @From=0,@[email protected]@ROWCOUNT
WHILE @From<@To
BEGIN
SET @[email protected]+1
SELECT @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(hostname) + ' '
+ 'testing "'
FROM #Rows WHERE [email protected]
print @msg
--EXEC (@msg)
END