Някои примери за нестандартни синтаксисни функции на Oracle SQL
Няколко думи за спецификата на поръчката по оператор
Какво мислите, ще има ли грешка в резултат на това искане?
Отговор: няма да има грешка, т.к. редът по спецификация се дефинира, както следва:ORDER BY [ASCDESC] [NULLS FIRSTLAST];Където изразът е израз на ключ за сортиране, като числови, низови и изрази за дата и час. Изразът може също да бъде израз на стойност на ред, като например скаларна подзаявка или израз на регистър. Повече подробности, например тук download.oracle.com/javadb/10.6.2.1/ref/rrefsqlj13658.html
Така сортирахме двойната таблица с израза "3X", който е безсмислен, но като израз за сортиране можете например да използвате израз с функцията substr. Самата възможност за използване на изрази е важна.
Тъй като знаем, че двойната таблица съдържа една колона, тази заявка ще върне ли грешка:
В първия случай имаме работа с позиционна индикация на колони - т.е. връзка към колона № 2, която не съществува, съответно ще получим грешка.
Във втория случай имаме работа с израз, т.е. това вече не е номер на колона, а сортиране по номер 2, подобно на сортирането по низа "3X" в заявка #1. Следователно няма да има грешка.
Вижте следния пример. Какъв ред ще получим в резултат на тази заявка? Ще има ли грешка?
Union all не сортира редовете на обединените множества (за разлика от union), т.е. без ред по , ще получим редовете в реда, посочен в заявката (съюзът all гарантира, че оригиналният ред на редовете е запазен). Сега е ред на реда по, основният въпрос е какво е "3" в този случай? Тъй като използваме двойни кавички ", а не единични кавички", тогава "3" е псевдоним на колона. Както знаете, операциите с набори изискват използването на подобни типове данни,и имената на колоните са взети от първата заявка, тъй като не сме посочили изрично името на първата колона, тогава по подразбиране тя получи името на израза, т.е. "3". Работата с такива псевдоними е показана например в заявка № 5 (основното е да не забравяте за главния регистър).
Сортирането по подразбиране винаги е възходящо, т.е. резултатите от заявка #4 са сортирани по първата колона във възходящ ред. Резултат: низ "2, X", след това "3, X".
Нека повторим експеримента от заявка #3 върху набори. Какъв ще бъде резултатът от искането?
Може да изглежда, че резултатът от заявката ще бъде следният: низът "3, X", след това "2, X". Предпоставките за това са следните: този ред гарантира обединение на всички и изразът 2+0 няма да повлияе на сортирането на записите (както е показано в заявка #7). Така би било, ако не беше едно „но“: при операции с набори подреждането по може да се използва само в края на съставна заявка с имена или номера на колони от първата заявка, изразите не са разрешени: Освен това клаузата ORDER BY може да се появи само в последната заявка за компонент. Клаузата ORDER BY подрежда всички редове, върнати от цялата съставна заявка. download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries005.htm#i2053998
Така че заявка #6 ще върне грешка.
Използване не в
Със сигурност повечето хора, които са преминали различни курсове, помнят, че операторът not in трябва да се избягва и подобна функционалност може да се получи с помощта на операторите in или exists. Причината за такова негативно отношение към не се крие в спецификата на работата му с нулеви стойности.
Определете резултата от изпълнението на следната заявка:
Като начало помислете за товазаявка:
Няма нищо необичайно в заявка #2: подзаявката връща набор от два реда със стойности "2" и "null", условието where се оценява на true, цялата заявка #2 връща 1 ред - стандартно поведение.
Сега нека да разгледаме разликата в поведението на in и не in, тук се нуждаем от знания за null аритметика: 1) Всички аритметични операции с null връщат null 2) Булеви оператори с null работят както следва:
- нула И невярно = невярно
- невярно И нула = невярно
- нула И вярно = нула
- вярно И нула = нула
- нула ИЛИ вярно = вярно
- вярно ИЛИ нула = вярно
- null ИЛИ false = null
- false ИЛИ null = нула
По този начин клаузата where в заявка #1 се оценява на нула, ако поне един операнд е нула, така че цялата заявка #1 е приблизително еквивалентна на следната заявка:
Очевидно заявка #3 няма да върне никакви редове, така че заявка #1 също няма да върне никакви редове.
Неявно преобразуване на типове
Темата за явното и неявното преобразуване на типове е много обширна, така че без да се опитвам да я обхвана като цяло, бих искал да разгледам само един пример. Нека днес 09/10/11 10:00:00 ч. и Oracle е конфигуриран така, че форматът DD.MM.RR да се разпознава по подразбиране, коя от заявките ще върне един ред?
Отговорът е и двете. Защо е това и как изобщо е възможно? Отговорът се крие в механизма на неявното преобразуване на типа.
Помислете за заявка номер 1: когато сравняваме датата с низ, в този случай Oracle опитвапреобразувайте низа в дата, ако форматът на низа съответства на един от форматите за дата по подразбиране (форматът за дата по подразбиране за сесия може да бъде намерен в параметъра NLS_DATE_FORMAT чрез изпълнение на заявката select * from nls_session_parameters). Ако форматът на низа не съответства на формата на датата по подразбиране, ще получим грешка. В нашия случай форматите съвпадат и низът „09/10/11“ се преобразува в датата 09/10/11 00:00:00, тъй като sysdate = 09/10/11 10:00:00, заявка #1 ще върне 1 ред.