Форум: "Прочее";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
ВнизКурсоры в SQL Server 2000 Найти похожие ветки
← →
@dim (2007-06-28 03:56) [0]Есть код, производящий некоторые изменения в БД:
WHILE Exists(SELECT FOperationKod FROM OperationNarad
WHERE NaradKod = @Kod)
BEGIN
SELECT @FKod = FOperationKod, @Count = Kolvo FROM OperationNarad
WHERE NaradKod = @Kod
--Увеличиваем невыполненные операции
UPDATE OperationForMake
SET ost = ost + @count
WHERE FOperationKod = @Fkod
DELETE FROM OperationNarad
WHERE FOperationKod = @FKod
END
DELETE FROM Narads
WHERE NaradKod = @kod
Хотелось бы сделать его более оптимальным. Пытался использовать курсор:declare cur cursor
local forward_only static
for SELECT @FKod = FOperationKod, @Count = Kolvo FROM OperationNarad WHERE NaradKod = @Kod
Open cur
Fetch next from cur
while @@fetch_status = 0
begin
fetch next from cur into @FKod, @Count
UPDATE OperationForMake
SET ost = ost + @count
WHERE FOperationKod = @Fkod
end
DELETE FROM Narads
WHERE NaradKod = @kod
Последний код не работает (не заходит в цикл). В чем может быть ошибка. Заранее спасибо!
← →
ЮЮ © (2007-06-28 05:52) [1]> Хотелось бы сделать его более оптимальным.
Что оптимизировал-то? И почему вдруг появление курсора чт-то оптимизирует?
1) зачем выделенное в запросе @FKod = FOperationKod, @Count = Kolvo ?
такая форма запроса не возвращает НД, поэтому и в цикл не входишь
оставь просто SELECT FOperationKod, Kolvo
2) место fetch next
такой порядок приаедет к пропуску первой записи курсора. Тебе это надо? если нет, то следует:
fetch next from cur into @FKod, @Count
while @@fetch_status = 0 begin
UPDATE OperationForMake
SET ost = ost + @count
WHERE FOperationKod = @Fkod
fetch next from cur into @FKod, @Count
end
P.S. y UPDATE есть FROM. Тогда можно вообще обойтись одним UPDATE-ом, безо всяких курсоров
← →
clickmaker © (2007-06-28 11:35) [2]
> fetch next from cur into @FKod, @Count
> while @@fetch_status = 0 begin
я обычно пишу так
while (1=1)
begin
fetch next from cur into @FKod, @Count
if @@fetch_status <> 0
break
end
чтоб не дублировать fetch next
← →
ЮЮ © (2007-06-28 11:42) [3]> P.S. y UPDATE есть FROM. Тогда можно вообще обойтись одним
> UPDATE-ом, безо всяких курсоров
см. http://delphimaster.net/view/3-1179472856/
← →
Ega23 © (2007-06-28 12:01) [4]
> clickmaker © (28.06.07 11:35) [2]
>
> я обычно пишу так
> while (1=1)
> begin
У меня рациональнее. Я пишуwhile (0=0)
. Ноль ближе на клаве к "равно", поэтому его нажимать легче. Значит - быстрее. Значит - рациональнее. :)))
← →
DiamondShark © (2007-06-28 12:12) [5]
> У меня рациональнее
А у меня нет.
declare <CursorName> cursor...
open <CursorName>
goto <CursorName>Fetch
<CursorName>Loop:
--TODO: Loop body
<CursorName>Fetch:
fetch next from <CursorName>...
if @@FETCH_STATUS=0 goto <CursorName>Loop:
забито как темплейт в КвериАнализер
← →
Ega23 © (2007-06-28 12:16) [6]
> DiamondShark © (28.06.07 12:12) [5]
Как-то неудобочитаемо...
Аж передёргивает от организации цикла через goto
Хотя для ТSQL - всё верно и прекрасно работать будет...
Close <CursorName>
Deallocate <CursorName>
ещё в конец темпдейта добавь.
← →
DiamondShark © (2007-06-28 12:22) [7]
> Аж передёргивает от организации цикла через goto
Так это ж не Паскаль ;)
меня самого передёргивает от использования flow-control операторов в SQL -- сразу появляется ощущение, что где-то когда-то что-то было неправильно сделано.
;)
← →
Anatoly Podgoretsky © (2007-06-28 12:29) [8]> Ega23 (28.06.2007 12:01:04) [4]
Он широкий, промахнуться тяжело.
← →
de. (2007-06-28 12:42) [9]
DECLARE
@Var1 int, @Var2 int, @Var3 int
DECLARE cur CURSOR FOR
SELECT Var1, Var2, Var3
FROM Table1
OPEN cur
FETCH NEXT FROM cur into @Var1, @Var2, @Var3
WHILE @@FETCH_STATUS = 0
BEGIN
/* деся твой запрос....
INSERT INTO tab_Ras(Var1, Var2, Var3)
VALUES (@Var1, @Var2, @Var3)
*/
FETCH NEXT FROM cur into @Var1, @Var2, @Var3
END
CLOSE cur
DEALLOCATE cur
← →
Павел Калугин © (2007-06-28 15:47) [10]
[0] @dim (28.06.07 03:56)
> Хотелось бы сделать его более оптимальным
Более оптимальным это вообще без цикла.
> [2] clickmaker © (28.06.07 11:35)
а я когда пытаюсь потом понять что значит while (1=1) рву на ...пе волоса
Спасибо, добрый человек дервиш Fetch перед циклом написать лень...
> [4] Ega23 © (28.06.07 12:01)
И ты брут???
← →
Павел Калугин © (2007-06-28 15:49) [11]> [0] @dim
И еще. если это отчет в диасофте то данный способ организации цикла оптимален. Ибо диасфт не всюду в отчетах понимает declare cursor
← →
Ega23 © (2007-06-29 09:03) [12]
> И ты брут???
Дык вот...
Как в BOL написано, так и делаю...
← →
ЮЮ © (2007-06-29 09:46) [13]Ega23 © (29.06.07 09:03) [12]
> Как в BOL написано, так и делаю...
В какой статье? А то мне попадаютя лишь:
Using WHILE...BREAK or CONTINUEUSE Northwind
GO
DECLARE abc CURSOR FOR
SELECT * FROM Shippers
OPEN abc
FETCH NEXT FROM abc
WHILE (@@FETCH_STATUS = 0)
FETCH NEXT FROM abc
CLOSE abc
DEALLOCATE abc
GO
или ещё круче:
WHILE
B. Using WHILE within a procedure with cursors
USE pubs
DECLARE tnames_cursor CURSOR
FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
OPEN tnames_cursor
DECLARE @tablename sysname
--SET @tablename = "authors"
FETCH NEXT FROM tnames_cursor INTO @tablename
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
BEGIN
SELECT @tablename = RTRIM(@tablename)
EXEC ("SELECT """ + @tablename + """ = count(*) FROM "
+ @tablename )
PRINT " "
END
FETCH NEXT FROM tnames_cursor INTO @tablename
END
CLOSE tnames_cursor
DEALLOCATE tnames_cursor
← →
Ega23 © (2007-06-29 09:52) [14]
OPEN authors_cursor
-- Perform the first fetch.
FETCH NEXT FROM authors_cursor
-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN
-- This is executed as long as the previous fetch succeeds.
FETCH NEXT FROM authors_cursor
END
Fetch Next идёт 2 раза. А можно одним обойтись.
← →
stone © (2007-06-29 10:18) [15]
> Fetch Next идёт 2 раза. А можно одним обойтись.
А какая разница? Зато так более читаемо.
> WHILE @@FETCH_STATUS = 0
А если курсор объявлен как DINAMIC, а какая-либо запись во время цикла была изменена или удалена? :)
← →
Ega23 © (2007-06-29 10:32) [16]
> А если курсор объявлен как DINAMIC, а какая-либо запись
> во время цикла была изменена или удалена? :)
Какая разница????
Ну сам посмотри. Просто в моём случае на одну строчку меньше писать, только и всего.
← →
stone © (2007-06-29 10:40) [17]
> Ega23 © (29.06.07 10:32) [16]
>
> > А если курсор объявлен как DINAMIC, а какая-либо запись
>
> > во время цикла была изменена или удалена? :)
>
>
> Какая разница????
DYNAMIC
Defines a cursor that reflects all data changes made to the rows in its result set as you scroll around the cursor. The data values, order, and membership of the rows can change on each fetch. The ABSOLUTE fetch option is not supported with dynamic cursors.
@@FETCH_STATUS
Returns the status of the last cursor FETCH statement issued against any cursor currently opened by the connection.
Return value Description
0 FETCH statement was successful.
-1 FETCH statement failed or the row was beyond the result set.
-2 Row fetched is missing.
← →
ЮЮ © (2007-06-29 11:05) [18]>
А если курсор объявлен как DINAMIC
[17] stone © (29.06.07 10:40)
значить покидать цикл надо при = -1, а не при <> 0. Хотя и в самом BOL не всегда это учитывают, судя по процитированным здесь примерам
← →
Павел Калугин © (2007-06-29 15:53) [19]> [16] Ega23 © (29.06.07 10:32)
и долго долго потом вкуривать что ца циклwhile true
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.072 c