Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
При выполнении курсора запрос, его определяющий, выполняется только один раз?
Дело в том, что я пытаюсь по ходу выполнения удалять записи в той же таблице, по которой еду.
4 окт 12, 14:31    [13267942]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
статический запрос не подойдёт?
4 окт 12, 14:32    [13267947]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
статический курсор, конечно
4 окт 12, 14:32    [13267953]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Glory
Member

Откуда:
Сообщений: 104760
defragmentator
При выполнении курсора запрос, его определяющий, выполняется только один раз?

Зависит от того, как вы определи свой курсор
Вы читали про параметры определения курсора ?
4 окт 12, 14:33    [13267959]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
У меня курсор по умолчанию. не знаю, чего там получается STATIC или DYNAMIC.

Мне как раз нужно наоборот, чтобы если я удалил запись, по которой ещё не проходил, чтобы она исключалась из выборки.
4 окт 12, 14:36    [13268006]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
defragmentator
У меня курсор по умолчанию. не знаю, чего там получается STATIC или DYNAMIC.

Мне как раз нужно наоборот, чтобы если я удалил запись, по которой ещё не проходил, чтобы она исключалась из выборки.

м.б. fetch_status = -2 ?
4 окт 12, 14:42    [13268086]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Glory
Member

Откуда:
Сообщений: 104760
defragmentator
У меня курсор по умолчанию. не знаю, чего там получается STATIC или DYNAMIC.

И что мешает узнать ?
4 окт 12, 14:43    [13268089]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
А если курсор READ_ONLY, то его можно сделать DYNAMIC ?
И ещё есть академический интерес, STATIC курсор работает быстрее, чем DYNAMIC ?
4 окт 12, 14:43    [13268096]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
defragmentator
У меня курсор по умолчанию. не знаю, чего там получается STATIC или DYNAMIC.

Мне как раз нужно наоборот, чтобы если я удалил запись, по которой ещё не проходил, чтобы она исключалась из выборки.
По-умолчанию динамический, если не ошибаюсь.
Если делается попытка фетчить удалённую запись, @@FETCH_STATUS устанавливается в -2.
Следовательно, внутри цикла надо IF @@FETCH_STATUS<>-2
http://msdn.microsoft.com/ru-ru/library/ms187308(v=sql.100).aspx

Когда-то в документации MS к старой версии сервера давался такой базовый шаблон:
DECLARE <Объявление списка переменных>;
DECLARE CursorName CURSOR ..... FOR SELECT ..../*Объявление курсора*/
OPEN CursorName;
FETCH NEXT FROM CursorName INTO <Список переменных>;
WHILE @@FETCH_STATUS<>-1
BEGIN
 IF @@FETCH_STATUS<>-2
 BEGIN
/*Здесь какие-то инструкции*/
 END;
 FETCH NEXT FROM CursorName INTO <Список переменных>;
END;
CLOSE CursorName;
DEALLOCATE CursorName;
4 окт 12, 14:55    [13268230]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
defragmentator
А если курсор READ_ONLY, то его можно сделать DYNAMIC ?
И ещё есть академический интерес, STATIC курсор работает быстрее, чем DYNAMIC ?
STATIC копирует все данные в tempdb, вообще-то...
У DYNAMIC свои тараканы - например, в очередной итерации цикла можно проапдейтить поле, использующееся в ORDER BY,
таким образом, что запись будет выбрана курсором ещё раз (он же моментально видит все изменения в записи, в том числе свои собственные).
А потом ещё и ещё...
Бесконечный цикл получится, однако.
4 окт 12, 15:00    [13268269]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
iap
У DYNAMIC свои тараканы - например, в очередной итерации цикла можно проапдейтить поле, использующееся в ORDER BY,
таким образом, что запись будет выбрана курсором ещё раз (он же моментально видит все изменения в записи, в том числе свои собственные).
А потом ещё и ещё...
Бесконечный цикл получится, однако.


Да, я склоняюсь к STATIC, и потом проверять просто каждый раз условие выборки, прежде чем обрабатывать очередную запись.
Интересно, по времени выполнения это = DYNAMIC ?
4 окт 12, 15:06    [13268310]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
defragmentator
iap
У DYNAMIC свои тараканы - например, в очередной итерации цикла можно проапдейтить поле, использующееся в ORDER BY,
таким образом, что запись будет выбрана курсором ещё раз (он же моментально видит все изменения в записи, в том числе свои собственные).
А потом ещё и ещё...
Бесконечный цикл получится, однако.


Да, я склоняюсь к STATIC, и потом проверять просто каждый раз условие выборки, прежде чем обрабатывать очередную запись.
Интересно, по времени выполнения это = DYNAMIC ?
Как это - "проверять каждый раз условие выборки"? Для чего?
Чтобы пропустить удалённую запись? Вы ответы вообще читаете?

Вообще, я тут старался не поднимать вопрос о целесообразности курсора в Вашем случае...
Но раз пошла такая пьянка, может, расскажете в двух словах о задаче?
Скорей всего ну его, этот курсор!
Хотя, всякое бывает, конечно...
4 окт 12, 15:12    [13268360]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
iap
defragmentator
У меня курсор по умолчанию. не знаю, чего там получается STATIC или DYNAMIC.

Мне как раз нужно наоборот, чтобы если я удалил запись, по которой ещё не проходил, чтобы она исключалась из выборки.
По-умолчанию динамический, если не ошибаюсь.
Если делается попытка фетчить удалённую запись, @@FETCH_STATUS устанавливается в -2.
Следовательно, внутри цикла надо IF @@FETCH_STATUS<>-2
http://msdn.microsoft.com/ru-ru/library/ms187308(v=sql.100).aspx

Когда-то в документации MS к старой версии сервера давался такой базовый шаблон:
DECLARE <Объявление списка переменных>;
DECLARE CursorName CURSOR ..... FOR SELECT ..../*Объявление курсора*/
OPEN CursorName;
FETCH NEXT FROM CursorName INTO <Список переменных>;
WHILE @@FETCH_STATUS<>-1
BEGIN
 IF @@FETCH_STATUS<>-2
 BEGIN
/*Здесь какие-то инструкции*/
 END;
 FETCH NEXT FROM CursorName INTO <Список переменных>;
END;
CLOSE CursorName;
DEALLOCATE CursorName;


По любому получается, что STATIC проще. Не нужно будет заморачиваться с @@FETCH_STATUS<>-2.
4 окт 12, 15:12    [13268368]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
iap
Как это - "проверять каждый раз условие выборки"? Для чего?
Чтобы пропустить удалённую запись? Вы ответы вообще читаете?

Вообще, я тут старался не поднимать вопрос о целесообразности курсора в Вашем случае...
Но раз пошла такая пьянка, может, расскажете в двух словах о задаче?
Скорей всего ну его, этот курсор!
Хотя, всякое бывает, конечно...


Если я буду использовать STATIC, то FETCH будет писать в переменные поля из удалённых записей. Так я понял?
Ведь запрос выполняется один раз, результат пишется в TempDB и оттуда FETCH будет писать данные в переменные.
А реально, удалена ли запись или нет, я узнаю отдельным запросом IF exists ....

Обойтись без курсора - вряд ли.
Я беру данные из одной системы и пишу в другую. При этом обновляю не только таблицу с данными, но и пишу в журнал, что я сделал.
Кроме того, ещё отлаживаю процесс, то есть вывожу через PRINT сообщения.
4 окт 12, 15:19    [13268426]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Вот, чтобы не быть голословным, текст:
  PRINT 'Пополнение т.с. и поиск дубликатов';
  DECLARE SUBJPOST CURSOR LOCAL READ_ONLY FOR SELECT [idPost], [PostName] FROM subj.[Post] WHERE ([idPost] NOT IN (SELECT [idPost] FROM map.[PostMap] WHERE [IdExtSystem]=2));  -- только то, чего ещё нет;
  OPEN SUBJPOST;
  FETCH SUBJPOST INTO @idPost, @subjPostName;
  WHILE @@FETCH_STATUS=0
  BEGIN
    PRINT @subjPostName; 
    SET @subjPostName1=dbo.Unify_Str(@subjPostName, @Correspondence);
    PRINT 'Unify_Str : '+@subjPostName1;

    -- Дубликаты текущей записи
    SELECT [idPost], [PostName]
    INTO #SUBJ_POSTS
    FROM subj.[Post]
    WHERE ([idPost]<>@idPost) and (dbo.Unify_Str([PostName], @Correspondence)=@subjPostName1);

    DECLARE DUPL_POST CURSOR LOCAL READ_ONLY FOR SELECT [idPost], [PostName] FROM #SUBJ_POSTS;
    OPEN DUPL_POST;
    FETCH DUPL_POST INTO @M_idPost, @subjPostName2;
    WHILE @@FETCH_STATUS=0
    BEGIN
      UPDATE subj.[DeptPost] SET [idPost]=@idPost WHERE [idPost]=@M_idPost;
      PRINT 'Удаление дубликата [idPost] = ' + convert(nvarchar(255), @M_idPost) + '   Наименование = ' + @subjPostName2;
      BEGIN TRAN DELPOST;
      INSERT INTO map.[PostLog] ([IdLog], [idPost],  [PostName],     [Action])
      VALUES                    (@idLog,  @M_idPost, @subjPostName2, 'D');
      DELETE FROM subj.[Post] WHERE [idPost]=@M_idPost;
      COMMIT TRAN DELPOST;

      FETCH DUPL_POST INTO @M_idPost, @subjPostName2;
    END;
    CLOSE DUPL_POST;
    DEALLOCATE DUPL_POST;

    DROP TABLE #SUBJ_POSTS;
4 окт 12, 15:22    [13268465]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Сорри, обкусил часть.
Вот полный текст:
  PRINT 'Пополнение т.с. и поиск дубликатов';
  DECLARE SUBJPOST CURSOR LOCAL READ_ONLY FOR SELECT [idPost], [PostName] FROM subj.[Post] WHERE ([idPost] NOT IN (SELECT [idPost] FROM map.[PostMap] WHERE [IdExtSystem]=2));  -- только то, чего ещё нет;
  OPEN SUBJPOST;
  FETCH SUBJPOST INTO @idPost, @subjPostName;
  WHILE @@FETCH_STATUS=0
  BEGIN
    PRINT @subjPostName; 
    SET @subjPostName1=dbo.Unify_Str(@subjPostName, @Correspondence);
    PRINT 'Unify_Str : '+@subjPostName1;

    -- Дубликаты текущей записи
    SELECT [idPost], [PostName]
    INTO #SUBJ_POSTS
    FROM subj.[Post]
    WHERE ([idPost]<>@idPost) and (dbo.Unify_Str([PostName], @Correspondence)=@subjPostName1);

    DECLARE DUPL_POST CURSOR LOCAL READ_ONLY FOR SELECT [idPost], [PostName] FROM #SUBJ_POSTS;
    OPEN DUPL_POST;
    FETCH DUPL_POST INTO @M_idPost, @subjPostName2;
    WHILE @@FETCH_STATUS=0
    BEGIN
      UPDATE subj.[DeptPost] SET [idPost]=@idPost WHERE [idPost]=@M_idPost;
      PRINT 'Удаление дубликата [idPost] = ' + convert(nvarchar(255), @M_idPost) + '   Наименование = ' + @subjPostName2;
      BEGIN TRAN DELPOST;
      INSERT INTO map.[PostLog] ([IdLog], [idPost],  [PostName],     [Action])
      VALUES                    (@idLog,  @M_idPost, @subjPostName2, 'D');
      DELETE FROM subj.[Post] WHERE [idPost]=@M_idPost;
      COMMIT TRAN DELPOST;

      FETCH DUPL_POST INTO @M_idPost, @subjPostName2;
    END;
    CLOSE DUPL_POST;
    DEALLOCATE DUPL_POST;

    DROP TABLE #SUBJ_POSTS;
    
    -- пополнение т.с.
    INSERT INTO map.[PostMap] ([IdPost], [IdExtSystem])
    VALUES (@idPost, 2);
    FETCH SUBJPOST INTO @idPost, @subjPostName;
  END;
  CLOSE SUBJPOST;
  DEALLOCATE SUBJPOST;
4 окт 12, 15:24    [13268477]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
denis2710
Member

Откуда: Москва
Сообщений: 3384
defragmentator,
И для чего же здесь нужны курсоры?
Дубликаты можно найти группировкой.Скалярная функция в where мощЪ,удаление в курсоре вообще мощЪ,примеры как делать не стоит.
Прочитайте про клауз output.
4 окт 12, 15:43    [13268634]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
defragmentator
По любому получается, что STATIC проще. Не нужно будет заморачиваться с @@FETCH_STATUS<>-2.
Наоборот.
Вначале всё копируется в tempdb и курсор ходит по копии.
А в это время кто-то удаляет записи в реальной базе.
Стало быть, курсор может наткнуться на записи, которых в реальности больше нет.

Динамический сразу видит, удалена запись или нет (она сразу пропадает из резалтсета).
Правда, как я думаю, постоянное отслеживание резалтсета исходного SELECTа курсора должно много ресурсов кушать.
В общем, надо пробовать. Но в первую очередь рассмотреть возможность полного отказа от курсора.
4 окт 12, 15:46    [13268659]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
defragmentator,

в двух словах слабО описать, что тут происходит?
И что надо было сделать?
4 окт 12, 15:47    [13268674]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
iap,

я уже сам запутался.
Вся процедура 1000 строк.
Из одной системы в другую копируется штатка.
Периодически поддерживается соответствие (дергается вся процедура).

В приведённом куске заполняется таблица соответствия (т.с.) и удаляются дубликаты для должностей целевой системы.
В журнал PostLog пишу, чего удалил.
Как - то так.

Понятно, приводить все 1000 строк не буду.
4 окт 12, 15:57    [13268760]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
denis2710
И для чего же здесь нужны курсоры?
Как буд-то они где-то вообще нужны.
Они только для императивистов, которые мало чё смысля в программировании.
Естественно что они путаются в 3х соснах. Ибо на 3х строчный запрос они пишут 1000че строчный кусок говно-кода.
4 окт 12, 17:40    [13269705]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Mnior,

Никогда не понимал людей, которые в своей жизни вместо написания программ занимаются прочтением умных книжек.
Увлекательно? Да. За прочтение платит богатый дядя.
Кстати, как запихнуть обновление 3-х разных таблиц в один запрос, Вы знаете?
Не написано это в Ваших книжках?:)
4 окт 12, 17:47    [13269756]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37069
defragmentator
Mnior,

Никогда не понимал людей, которые в своей жизни вместо написания программ занимаются прочтением умных книжек.
Увлекательно? Да. За прочтение платит богатый дядя.
Кстати, как запихнуть обновление 3-х разных таблиц в один запрос, Вы знаете?
Не написано это в Ваших книжках?:)
Да нет же. Не увлекательно. Можно ведь не читать ничего и такие классные темы на форуме пилить. Вот это реально увлекательно!
4 окт 12, 17:50    [13269788]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Glory
Member

Откуда:
Сообщений: 104760
defragmentator
Кстати, как запихнуть обновление 3-х разных таблиц в один запрос, Вы знаете?
Не написано это в Ваших книжках?:)

Это называется триггер
4 окт 12, 17:55    [13269825]     Ответить | Цитировать Сообщить модератору
 Re: Подскажите про курсор  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
defragmentator
Никогда не понимал людей, которые в своей жизни вместо написания программ занимаются прочтением умных книжек. Увлекательно? Да. За прочтение платит богатый дядя.
На столько ли тонка грань между построением модели и придумыванием сказок?
Книги не достаточное условие. Да и не обязательное.

Триггер? Да. Но не обязательно.

PS: Да, очень мало книг читал, можно сказать не читал вообще.
4 окт 12, 18:13    [13269956]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить