Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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 CONTINUE

USE 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.047 c
15-1182925482
iXT
2007-06-27 10:24
2007.07.29
OLE Server


15-1182871267
oldman
2007-06-26 19:21
2007.07.29
Ну... поскольку недавно сбрил бороду и усы...


15-1183246624
Kostafey
2007-07-01 03:37
2007.07.29
С днем рождения ! 1 июля


4-1171270394
Чапаев
2007-02-12 11:53
2007.07.29
Как потоку получить оповещение о выходе из suspend?


15-1183099714
hgd
2007-06-29 10:48
2007.07.29
Алгоритм Magic wand





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский