Конференция "Базы" » как это будет для MSSQL? [D7, MSSQL]
 
  • DSKalugin © (24.12.08 15:17) [0]
    В хранимых процедурах Firebird я бы решил эту задачу так

    for
     select ...
     from ...
     where ...
     into ...
    do begin
     <построчная работа с переменными из into>
     if <условие> then suspend; --выдача записи
    end


    а как это сделать в MSSQL?
  • Медвежонок Пятачок © (24.12.08 15:19) [1]
    декларе курсор аз
    опен
    вайл фетчстатус ноль
    слщыу
  • Ega23 © (24.12.08 15:23) [2]
    declare @x int;

    declare cur cursor [local] [static] for
     select x from table into @x;
    open cur;
    while(0=0)  
    begin
     if @@fetch_status<>0 break;
     ..... Работа с @x;
    end;
    close cur;
    deallocate cur;

  • DSKalugin © (24.12.08 15:53) [3]
    Тут можно пояснить?

    if @@fetch_status<>0 break;
    ..... Работа с @x;


    брейк разве не выход из цикла?
    и почему сначала проверка, а потом работа если сначала нужно проверить
    и если естина то выдать запись в результат хп
    результатом должна быть не одна строка а выборка, отфильтроованная по сложным критериям
  • Медвежонок Пятачок © (24.12.08 15:56) [4]
    открыть курсор.
    шлепать по нему и вычислять сложное условие.
    если да, то инсерт в темповую таблицу.

    в конце селект из темповой таблицы.
  • Ega23 © (24.12.08 16:18) [5]

    > брейк разве не выход из цикла?


    выход.


    > и почему сначала проверка, а потом работа если сначала нужно
    > проверить
    > и если естина то выдать запись в результат хп


    Мы о чём сейчас говорим? О том, как сформировать выходной набор данных из ХП? Так это просто Select, без всяких там курсоров.
    Например:

    CREATE PROCEDURE S_Test
     @Param int =0
    as

    if @Param=1
    begin
     Select newid();
    end;

    if @Param=2
    begin
     Select getdate();
    end;

    if @Param=3
    begin
     Select * from sysobjects;
    end;

    if @Param=4
    begin
     insert into test (column1) values (@Param);
    end;

    if @param=5
    begin
     Delete from test where column1=@param;
    end;



    Если нужно какие-то данные собрать, потом их построчно как-то обработать и потом обработанные выдать в качестве результата, то заводится временная таблица, в неё собираются данные, объявляется курсор, обходим эту таблицу, колдуем над записями и потом Select из неё делаем.
  • Павел Калугин © (06.01.09 09:56) [6]
    > [2] Ega23 ©   (24.12.08 15:23)
    > while(0=0)  
    > begin
    > if @@fetch_status<>0 break;
    > ..... Работа с @x;



    а почемиу не
    while @@fetch_status=0


    в чем разница?
  • Ega23 © (11.01.09 13:30) [7]

    > а почемиу не
    > while @@fetch_status=0
    >
    > в чем разница?


    Пардон, я Fetch Next пропустил, должно перед проверкой стоять.
  • Павел Калугин © (11.01.09 15:32) [8]
    Все равно не понимаю. В чем разница ? в привычке? или есть объективные причины?

    Ну приведем полную конструкцию
    declare cur cursor  for select a,b,c from t where bla nla bla
    open cur
    fetch  cur into @a,@b,@c
    while @@fetch_status=0
    begin
     // работа с @a,@b,@c
     fetch  cur into @a,@b,@c
    end
    close cur
    deallocate cur



    и

    declare cur cursor  for select a,b,c from t where bla nla bla
    open cur
    while 0=0
    begin
     fetch  cur into @a,@b,@c
     if @@fetch_status != 0  break
        // работа с @a,@b,@c
    end
    close cur
    deallocate cur

  • Ega23 © (11.01.09 16:45) [9]

    > Все равно не понимаю. В чем разница ? в привычке? или есть
    > объективные причины?


    Если честно, то меня ломает 2 раза Fetch Next писать.
    И потом, я тоже не вижу разницы - один раз сделать фетч и войти в цикл по статусу, или войти в бесконечный цикл с брейком по статусу.
    В BOL для 7.0 были и такие и такие примеры. В BOL для 2000 - вроде тоже (сейчас искать лень). Сейчас я уже давно не видел примеров с бесконечным циклом. Но и нигде не видел, что так делать нельзя.
  • Павел Калугин © (12.01.09 10:10) [10]
    > [9] Ega23 ©   (11.01.09 16:45)

    да дело просто в другом
    я умом понимаю что работают оба варианта
    а вот смысл? Не пишем лишний ращз фетч и ломаем нисходящую стуктуру?
    или все-таки есть смысл в подобном синтаксисе? скорость работы там. или тонкости обработки сервером?

    ведь можно написать цикл
    i:=1;
    while i<100 do
    begin
     println(i);
     inc(i);
    end

    а можно написать
    i:=0;
    while true do
    begin
     inc(i);
     if i=100 then break ; (или stop или exit? что тама положено)
     println(i);
    end

    результат будет один колонка цифирей от 1 до 99  
    но где будет правильно?
  • Павел Калугин © (12.01.09 10:14) [11]
    вот например есть боллшая система, опердень банка. до недавнего времени она в отчетах не понимала курсоров. приходилось городить временную табличку с автоинкрементным айдишником и по циклу получать минимальный ид, обрабатывать селект из временной таблички по этому ид, удалять из временной таблички запись с таким ид. Понятно курсор проще, меньше букав писать но обработчик встроеный их не понимает.
    так может и тут какие то подобные уши торчат?
  • clickmaker © (12.01.09 14:24) [12]
    > результат будет один колонка цифирей от 1 до 99  
    > но где будет правильно?

    да без разницы
    где работает правильно - там и правильно
  • Павел Калугин © (12.01.09 14:31) [13]

    > clickmaker ©   (12.01.09 14:24) [12]


    var b : boolean;
    begin
       if b = true then b:=false else b:= true;
    end

    тоже работает правильно но прочему то за такое руки отрывают и заставляют писать

    b:=not b;

    утверждая что первое неверно.
  • clickmaker © (12.01.09 14:38) [14]
    > тоже работает правильно но прочему то за такое руки отрывают

    я бы такое не написал только потому, что движений больше совершать -)
    кстати, как и в случае с двумя фетчами
  • Ega23 © (12.01.09 15:57) [15]

    > тоже работает правильно но прочему то за такое руки отрывают
    > и заставляют писать


    Ещё раз: в одном варианте BOL видел примеры как с бесконечным циклом, так и с двумя фетчами. И, кстати, видел в одном и том же BOL примеры объединения как с left join так и с from ... where ...

    Скорее всего привели к общему стилю написания справки.
  • Павел Калугин © (13.01.09 01:07) [16]
    > [15] Ega23 ©   (12.01.09 15:57)

    Спасибо, понял...
    Резюме - разницы никакой кто как привык....


    > [14] clickmaker ©   (12.01.09 14:38)
    > кстати, как и в случае с двумя фетчами

    ctrl+C ctrl+V - больше движений?
    ну, кто как привык...
  • Ega23 © (13.01.09 10:47) [17]

    > ctrl+C ctrl+V - больше движений?
    > ну, кто как привык...


    Это хорошо, когда у тебя одна-три переменные, в которые фетч идёт. А когда 20?
  • Павел Калугин © (13.01.09 14:24) [18]
    а какая разница копировать строку с 20 или с 1 переменной?
    зато читать удобнее без этих "прыжков наружу" :)
  • Ega23 © (13.01.09 14:35) [19]

    > зато читать удобнее без этих "прыжков наружу" :)


    Кому как.
  • Павел Калугин © (13.01.09 16:55) [20]

    > Ega23 ©   (13.01.09 14:35) [19]


    А о привычках все же лучше под пивко трындеть:)
 
Конференция "Базы" » как это будет для MSSQL? [D7, MSSQL]
Есть новые Нет новых   [134477   +42][b:0][p:0.002]