Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.61.145] |
|
Данный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ. |
Сообщ.
#1
,
|
|
|
Добрый день!
Возникла необходимость писать и понимать SQL. Вникаю потихоньку. Изучаю функции и скрипты в базе с которой надо работать. Пока не всё ясно. Есть такой вот код: 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? Или просто описать алгоритм этой функции обычным русским языком. Там я уже разберусь до конца. |
Сообщ.
#2
,
|
|
|
Что за диалект? Оракл? Никогда с ним не сталкивался.
В принципе, тут все ясно: - rec - это имя переменной, которая хранит текущую запись из итерируемого набора - for loop итерирует набор значений, в данном случае строки, возвращенные select-ом - end NAME в данном случае это конец блока case (end) и псевдоним для выбираемого значения (NAME) - второй возврат нужен потому, что первый не сработает, если в наборе нет записей Функция возвращает значение из одной записи из таблицы (если есть хоть одна подходящая), либо null (если такой записи нет). Для этого выбираются значения по критерию, затем цикл обрабатывает выборку (или там, в нутре, не готовая выборка, а курсор дергается?), но на первой же итерации цикл грубо обрывается и возвращается поле первой записи из выборки. Если же выборка пуста, то цикл вообще не выполняется, и срабатывает return (null). P. S. Может, рановато еще в рабочий код смотреть? Ораклами, вроде бы, пользуются серьезные фирмы для серьезного бизнеса. Можно серьезно накосячить. |
Сообщ.
#3
,
|
|
|
Если
Цитата AVA12 @ на первой же итерации цикл грубо обрывается то ето не очень хороший код. Запрос должен возврашать не более одной записи. В код надо добавить TOP 1 или LIMIT 0, 1 или ограничитель количества записей етого диалекта SQL. |
Сообщ.
#4
,
|
|
|
Ну и ORDER BY надо добавить потому, как ета функция недетерминирована. Она может возврашать разные результаты при множественных вызовах на одних и тех же данных.
|
Сообщ.
#5
,
|
|
|
Цитата AVA12 @ для работы используется Oracle SQL Developer, это всё, что могу сказать. Если есть способы проверить диалект, напишите, сделаю.Что за диалект? Оракл? Никогда с ним не сталкивался. Со знанием названия диалекта гуглить явно станет легче. Цитата AVA12 @ Я когда впервые увидел этот код, загуглил for-loop и мне "повезло": попал на сайт, на котором рассказывалось только о числовой форме for. Вооружившись этими знаниями я конечно наглухо "завис" на разборе этой функции.- rec - это имя переменной, которая хранит текущую запись из итерируемого набора - for loop итерирует набор значений, в данном случае строки, возвращенные select-ом Прочитал ответы, погуглил ещё... А тут курсорная форма Цитата AVA12 @ Да, так и есть. Серьёзная фирма для серьёзного бизнеса. Но это обязывает: бардак тут тоже серьёзный Ораклами, вроде бы, пользуются серьезные фирмы для серьезного бизнеса. И я не разработчик, а пользователь. Так что программисты отмахиваюся: иди нафиг, не мешай, а коллеги знают примерно с моё. Цитата AVA12 @ Нельзя: у меня доступ только на чтение Может, рановато еще в рабочий код смотреть? Можно серьезно накосячить. Цитата MIF @ то ето не очень хороший код. Запрос должен возврашать не более одной записи. Меня вот тоже такой подход как-то коробит с первого взгляда. Таблица из которой делается select - справочник, а параметр функции - идентификатор, который обязан быть уникальным в таблице. Иначе что это за идентификатор такой? Цитата MIF @ если правильно помню, здесь это rownum <=1В код надо добавить TOP 1 или LIMIT 0, 1 или ограничитель количества записей етого диалекта SQL. Вот так можно переписать? 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 надо добавить Он что, сначала отбирает все записи, а потом выбрасывает лишние, чтобы осталось сколько просили? |
Сообщ.
#6
,
|
|
|
Цитата SV() @ Если ограничиваем количество записей одной, то всё равно нужна сортировка? Да. SQL движки не гарантируют порядок записей в рекордсете если нет сортировки. Цитата SV() @ Он что, сначала отбирает все записи, а потом выбрасывает лишние, чтобы осталось сколько просили? Нет. Движок проводит seek или scan таблицы или индекса и останавливается когда найдено нужное число записей. |
Сообщ.
#7
,
|
|
|
Я по ходу как-то неправильно понимаю параметр ORDER BY.
я считал, что сначала выполняется собственно SELECT со всеми условиями. В итоге получается некая табличка-результат. И вот она то уже сортируется в соответствии с ORDER BY. Нет? |
Сообщ.
#8
,
|
|
|
Цитата SV() @ я считал, что сначала выполняется собственно SELECT со всеми условиями. В итоге получается некая табличка-результат. И вот она то уже сортируется в соответствии с ORDER BY. Нет? Индекс решает все. Если поле в WHERE фильтре и в ORDER BY и есть TOP N и: 1. поле проиндексировано: запрос найдет первую запись в индексе с нужным значением, а потом просканирует индекс пока не найдет нужное количество записей либо пока значение индекса не выйдет за условие WHERE. 2. не проиндексировано: запрос просканирует всю таблицу, потом упорядочит найденные записи, пором выберет TOP N из результата. |