На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Pr0[)!9Y, Akina, JoeUser
  
> Помогите прочесть код, Что точно делает эта SQL функция?
Добрый день!

Возникла необходимость писать и понимать SQL. Вникаю потихоньку. Изучаю функции и скрипты в базе с которой надо работать.
Пока не всё ясно.
Есть такой вот код:
ExpandedWrap disabled
    create or replace
    FUNCTION GET_LABEL
      (Clas IN SMF.clas%Type,
        inMask in Integer default 0
       )
    RETURN SMF.name%Type
    IS
     
    BEGIN
    for rec in ( select case inMask
                              when 1 then Decode ( Tabl.TIP, 1, Tabl.NUM, Tabl.NAME )
                              else Tabl.NAME
                              end NAME
                    from base.TABLE_1 Tabl
                    where ( Tabl.CLAS = Clas ) or
                          ( Tabl.FILIAL = Clas ) ) loop
        Return (rec.NAME) ;
    end loop;
    Return ( Null );
    END GET_LABEL;
Пока не всё тут понятно.
В принципе основные проблемы с пониманием:
- кто такой rec?
- зачем тут for-loop? Что он делает?
- что такое end NAME?
- почему два Return?

Или просто описать алгоритм этой функции обычным русским языком. Там я уже разберусь до конца.
Лучше день потерять, но потом за 5 минут долететь
Что за диалект? Оракл? Никогда с ним не сталкивался.

В принципе, тут все ясно:

- rec - это имя переменной, которая хранит текущую запись из итерируемого набора
- for loop итерирует набор значений, в данном случае строки, возвращенные select-ом
- end NAME в данном случае это конец блока case (end) и псевдоним для выбираемого значения (NAME)
- второй возврат нужен потому, что первый не сработает, если в наборе нет записей

Функция возвращает значение из одной записи из таблицы (если есть хоть одна подходящая), либо null (если такой записи нет). Для этого выбираются значения по критерию, затем цикл обрабатывает выборку (или там, в нутре, не готовая выборка, а курсор дергается?), но на первой же итерации цикл грубо обрывается и возвращается поле первой записи из выборки. Если же выборка пуста, то цикл вообще не выполняется, и срабатывает return (null).

P. S. Может, рановато еще в рабочий код смотреть? Ораклами, вроде бы, пользуются серьезные фирмы для серьезного бизнеса. Можно серьезно накосячить.
Если
Цитата AVA12 @
на первой же итерации цикл грубо обрывается

то ето не очень хороший код. Запрос должен возврашать не более одной записи. В код надо добавить TOP 1 или LIMIT 0, 1 или ограничитель количества записей етого диалекта SQL.
Мои религиозные убеждения не позволяют мне комментировать код.
Моё мировоззренье таково: в программе комментария ни одного!
Ну и ORDER BY надо добавить потому, как ета функция недетерминирована. Она может возврашать разные результаты при множественных вызовах на одних и тех же данных.
Мои религиозные убеждения не позволяют мне комментировать код.
Моё мировоззренье таково: в программе комментария ни одного!
Цитата AVA12 @
Что за диалект? Оракл? Никогда с ним не сталкивался.
для работы используется Oracle SQL Developer, это всё, что могу сказать. Если есть способы проверить диалект, напишите, сделаю.
Со знанием названия диалекта гуглить явно станет легче.

Цитата AVA12 @
- rec - это имя переменной, которая хранит текущую запись из итерируемого набора
- for loop итерирует набор значений, в данном случае строки, возвращенные select-ом
Я когда впервые увидел этот код, загуглил for-loop и мне "повезло": попал на сайт, на котором рассказывалось только о числовой форме for. Вооружившись этими знаниями я конечно наглухо "завис" на разборе этой функции.
Прочитал ответы, погуглил ещё... А тут курсорная форма :blush:

Цитата AVA12 @
Ораклами, вроде бы, пользуются серьезные фирмы для серьезного бизнеса.
Да, так и есть. Серьёзная фирма для серьёзного бизнеса. Но это обязывает: бардак тут тоже серьёзный :bad:
И я не разработчик, а пользователь. Так что программисты отмахиваюся: иди нафиг, не мешай, а коллеги знают примерно с моё.
Цитата AVA12 @
Может, рановато еще в рабочий код смотреть? Можно серьезно накосячить.
Нельзя: у меня доступ только на чтение :ph34r:

Цитата MIF @
то ето не очень хороший код. Запрос должен возврашать не более одной записи.
:yes:
Меня вот тоже такой подход как-то коробит с первого взгляда.
Таблица из которой делается select - справочник, а параметр функции - идентификатор, который обязан быть уникальным в таблице. Иначе что это за идентификатор такой?
Цитата MIF @
В код надо добавить TOP 1 или LIMIT 0, 1 или ограничитель количества записей етого диалекта SQL.
если правильно помню, здесь это rownum <=1

Вот так можно переписать?
ExpandedWrap disabled
    create or replace
    FUNCTION GET_LABEL
      (Clas IN SMF.clas%Type,
        inMask in Integer default 0
       )
    RETURN SMF.name%Type
    IS
     
    BEGIN
    ( select case inMask
             when 1 then Decode ( Tabl.TIP, 1, Tabl.NUM, Tabl.NAME )
             else Tabl.NAME
             end NAME
      from base.TABLE_1 Tabl
      where (( Tabl.CLAS = Clas ) or ( Tabl.FILIAL = Clas )) and rownum <=1
    ) ResultTable
     
    Return (ResultTable.NAME) ;
     
    END GET_LABEL;


Цитата MIF @
и ORDER BY надо добавить
Если ограничиваем количество записей одной, то всё равно нужна сортировка?
Он что, сначала отбирает все записи, а потом выбрасывает лишние, чтобы осталось сколько просили? :blink:
Лучше день потерять, но потом за 5 минут долететь
Цитата SV() @
Если ограничиваем количество записей одной, то всё равно нужна сортировка?


Да. SQL движки не гарантируют порядок записей в рекордсете если нет сортировки.
Цитата SV() @
Он что, сначала отбирает все записи, а потом выбрасывает лишние, чтобы осталось сколько просили?


Нет. Движок проводит seek или scan таблицы или индекса и останавливается когда найдено нужное число записей.
Мои религиозные убеждения не позволяют мне комментировать код.
Моё мировоззренье таково: в программе комментария ни одного!
Я по ходу как-то неправильно понимаю параметр ORDER BY.
я считал, что сначала выполняется собственно SELECT со всеми условиями. В итоге получается некая табличка-результат. И вот она то уже сортируется в соответствии с ORDER BY. Нет?
Лучше день потерять, но потом за 5 минут долететь
Цитата SV() @
я считал, что сначала выполняется собственно SELECT со всеми условиями. В итоге получается некая табличка-результат. И вот она то уже сортируется в соответствии с ORDER BY. Нет?


Индекс решает все.
Если поле в WHERE фильтре и в ORDER BY и есть TOP N и:
1. поле проиндексировано: запрос найдет первую запись в индексе с нужным значением, а потом просканирует индекс пока не найдет нужное количество записей либо пока значение индекса не выйдет за условие WHERE.
2. не проиндексировано: запрос просканирует всю таблицу, потом упорядочит найденные записи, пором выберет TOP N из результата.
Мои религиозные убеждения не позволяют мне комментировать код.
Моё мировоззренье таково: в программе комментария ни одного!
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script Execution time: 0,1157 ]   [ 20 queries used ]   [ Generated: 20.03.19, 19:44 GMT ]