Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

УП СУБД ч1

.pdf
Скачиваний:
14
Добавлен:
11.06.2015
Размер:
1.05 Mб
Скачать

SELECT LAST_DAY( SYSDATE ),

LAST_DAY( SYSDATE ) - SYSDATE «осталось»

FROM DUAL;

(7.9)

 

 

 

 

 

LAST_DAY(SYSDATE)

осталось

 

 

31-JUL-08

2

 

Рис. 7.9. Значение запроса 7.9

Кроме того, существуют функции ADD_MONTH, MONTH_BETWEEN, NEXT_DAY и др.

Теперь рассмотрим вопрос преобразования типов при вычислении выражений. В качестве примера приведем три запроса:

SELECT item + price FROM acceptedorders;

(7.10)

SELECT item || price FROM acceptedorders;

(7.11)

SELECT item || TO_CHAR( price )

(7.12)

FROM acceptedorders;

Из них первый запрос 7.10 является некорректным и не будет вычислен, поскольку тип поля item – строка, тип поля price – число, а оператор «+» применяется только к числовым значениям. Второй запрос, однако, будет выполнен, несмотря на то, что оператор «||» применяется только к строковым значениям, и сформирует следующую выборку:

ITEM||PRICE

Watch 199.99

Book 12.5

Pizza 5.5

PS3 400

Pizza 5.5

Book 12.5

DVD Disk 6.35

Рис. 7.10. Значение запроса 7.11

Разница состоит в том, что перед вычислением выражений производится попытка преобразования операндов к типу, который требуется при вычислении данной операции.

71

В первом случае, поскольку оператор «+» – арифметический, произойдет попытка преобразовать значения поля item в значения целого типа, причем преобразованы должны быть значения этого поля во всех строках, которые используются в запросе. Однако конкретные значения ‘Watch’, ‘Book’ не могут быть преобразованы в числа, поэтому запрос 7.9 является ошибочным с точки зрения исполнения, хотя синтаксически он правильный. Например, следующий запрос будет выполнен, поскольку значение ‘134’ допускает преобразование в число:

SELECT ‘123’ + price FROM acceptedorders

(7.13)

Во втором случае, при вычислении запроса 7.11, оператор «||» строковый, а числовые значения (поле price) всегда преобразуются в строки.

Преобразование типов бывает явное и неявное. В запросах 7.10,7.11 используется неявное преобразование, которое автоматически выполняется интерпретатором при выполнении запроса, причем правила преобразования фиксированы и описаны в документации. При явном преобразовании необходимо использовать специальные функции, при помощи которых можно явно указать желаемый способ преобразования значений к необходимому виду. Явное преобразование является более гибким и в некоторых случаях более предсказуемым и поэтому предпочтительным. Запрос 7.12 иллюстрирует простейший способ использования явного преобразования.

К функциям преобразования типов относятся функции

TO_CHAR(), TO_NUMBER(), TO_DATE(); вторым параметром этих функций обычно является специальная строка, определяющая способ форматирования значения. Ниже приведены примеры основных способов использования этих функций.

Запрос 7.14 преобразует числовое значение поля price в формат для денежного представления и в значение в научном формате.

SELECT price, TO_CHAR( price, ‘U999,000.99’ ),

 

TO_CHAR( price, ‘9.9EEEE’ )

(7.14)

FROM acceptedorders;

72

PRICE

TO_CHAR(PRICE,’U999,000.99’)

TO_CHAR(PRICE,’9.9EEEE’)

199.99

$199.99

2.0E+02

12.5

$012.50

1.3E+01

5.5

$005.50

5.5E+00

400

$400.00

4.0E+02

5.5

$005.50

5.5E+00

12.5

$012.50

1.3E+01

6.35

$006.35

6.4E+00

Рис. 7.11. Значение запроса 7.14

Запрос 7.15 иллюстрирует вывод даты в различных форматах.

SELECT SYSDATE,

TO_CHAR( SYSDATE, ‘DD, Day Month YYYY’ )

«DD, Day Month YYYY»,

 

TO_CHAR( SYSDATE, ‘DD MM YYYY’ )

(7.15)

«DD MM YYYY» FROM DUAL

 

 

 

 

SYSDATE

DD, Day Month YYYY

 

DD MM YYYY

22-AUG-08

22, Friday August 2008

 

22 08 2008

Рис. 7.12. Значение запроса 7.15

При форматировании значений-дат можно использовать значения форматеров, приведенных в таблице 4.

Помимо многочисленных функций преобразования вида TO_XXXX(), можно использовать функцию CAST, имеющую следующий синтаксис:

CAST( выражение AS тип )

Эта функция выполняет преобразование значения выражения к указанному типу, если это возможно. Ниже приведены примеры преобразования типов при помощи этой функции.

SELECT name,

 

CAST( name AS VARCHAR(3) ) «VARCHAR(3)»,

 

CAST( name AS CHAR(3) ) «CHAR(3)»

(7.16)

FROM student

73

NAME

VARCHAR(3)

CHAR(3)

Jane

Jan

Jan

Bill

Bil

Bil

Polie

Pol

Pol

Gill

Gil

Gil

Рис. 7.13. Значение запроса 7.16

Помимо преобразования собственно типа значений, функцию CAST можно использовать для изменения длины строковых значений, значение при этом усекается до требуемой длины, как в предыдущем примере.

Оператор CASE предназначен для замены одних значений на другие, в зависимости от выполнения логических условий, и напоминает операторы IF и SWITCH в процедурных языках программирования. Оператор CASE имеет два варианта. Синтаксис и использование первого варианта иллюстрирует следующий запрос 7.17:

SELECT DISTINCT student,

CASE student WHEN ‘Bill’ THEN student || ‘-Boy’ WHEN ‘Polie’ THEN ‘My Lovely ‘ || student WHEN ‘Jane’ THEN ‘Naughty ‘ || student

ELSE student || ‘...Who is that? ‘

END «An Opinion»

(7.17)

FROM CourseResult

 

 

 

 

 

STUDENT

An Opinion

 

 

Bill

Bill -Boy

 

 

Jane

Naughty Jane

 

 

Polie

My Lovely Polie

 

Рис. 7.14. Значение запроса 7.17

Выражение после служебного слова CASE вычисляется и затем последовательно сравнивается со значениями, перечисляемыми в каждой конструкции WHEN; при совпадении с одним из этих значений в качестве значения оператора берется значение выражения после соответствующего THEN. Если значение ни в одном из выражений WHEN не найдено,

74

используется значение после слова ELSE. Конструкцию CASE завершает ключевое слово END.

Во втором варианте оператора CASE после слова WHEN используется логическое выражение, а не литеральная конс­ танта, как в первом варианте:

SELECT student || ‘ gets ‘ || CASE WHEN Result = 5 THEN ‘A’ WHEN Result = 4 THEN ‘B’

WHEN Result = 3 THEN ‘C’

WHEN Result IS NULL THEN ‘nothing’

ELSE ‘..What is that? ‘

 

END «Result»

(7.18)

FROM CourseResult

Примечание: Пустые значения NULL подробнее рассмотрены в разделе 10.

Result

Bill gets A

Polie gets nothing

Jane gets A

Jane gets B

Bill gets nothing

Рис. 7.15. Значение запроса 7.18

Существует также функция DECODE, аналогичная оператору CASE; эта функция использовалась в более ранних версиях Oracle. Ниже приведен запрос 7.19, аналогичный запросу 7.18, реализованный с использованием функции

DECODE:

SELECT student || ‘ gets ‘ ||

DECODE( Result, 5, ‘A’,

 

4, ‘B’,

 

 

3, ‘C’,

 

 

NULL, ‘nothing’,

 

...What is that? ‘ ) «Result»

(7.19)

FROM CourseResult

75

Выводы

использование встроенных функций существенно расширяет возможности обработки данных при помощи языка SQL;

вычислить значение некоторой функции можно при помощи следующего запроса:

SELECT <имя функции> FROM DUAL;

к математическим функциям относятся алгебраические (SQRT, POWER), тригонометрические (SIN, COS и т.д.), а также функции округления (FLOOR, CEIL, ROUND, TRUNC);

строковые функции (LPAD, LTRIM, UPPER, REPLACE, SUBSTR, LENGTH и др.) предназначены главным образом для преобразования строковых значений;

строковые функции корректно работают со строковыми значениями национальных алфавитов;

к функциям для работы со значениями-датами относятся функции SYSDATE и LAST_DAY, а также функции TRUNC и ROUND, выполняющие округление значений-дат;

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

для выполнения явного преобразования типов используются функции TO_CHAR(), TO_NUMBER(), TO_DATE(), а также CAST();

оператор CASE предназначен для замены одних значений на другие, в зависимости от выполнения логических условий, и напоминает операторы IF и SWITCH в процедурных языках программирования.

Вопросы для контроля

1.Какие преимущества обеспечивает использование встроенных функций в выражениях языка SQL?

2.Перечислите основные строковые функции языка SQL Oracle.

76

3.Объясните различия между явным и неявным способами преобразования типов.

4.Перечислите функции округления и объясните различия между ними.

5.Приведите примеры использования функции TO_ CHAR() для преобразования значений дат в строки с различными форматерами.

6.Объясните различия между двумя вариантами оператора CASE.

77

Раздел 8. Язык Oracle SQL. Использование селекции данных

Данный раздел посвящен описанию средств языка SQL Oracle для построения запросов с селекций.

Для спецификации условий селекции записей исходной таблицы используется логическое выражение, указываемое после слова WHERE, которое может включать, помимо арифметических и строковых операций и функций, операции сравнения ( <, >, =, <> или !=, >=, <= ), логические операции AND, OR и NOT и специальные предикаты.

Ниже приведены простые примеры использования логических выражений. Запрос 8.1 позволяет выбрать заказы, относящиеся к заказчику ‘Ms.Magpie’.

SELECT item, price, quantity, customer_address

 

FROM acceptedorders

 

(8.1)

WHERE customer_name = ‘Ms.Magpie’ ;

 

 

 

 

ITEM

PRICE

QUANTITY

CUSTOMER_ADDRESS

Book

12.5

1

Pall Mall, 3

 

Pizza

5.5

3

Pall Mall, 3

 

PS3

400

1

Pall Mall, 3

 

Рис. 8.1. Значение запроса 8.1

Запрос 8.2. выбирает заказы с общей стоимостью более 100:

SELECT item, price, quantity, customer_address

FROM acceptedorders

 

WHERE price * quantity > 100;

(8.2)

 

 

 

 

ITEM

PRICE

QUANTITY

CUSTOMER_ADDRESS

Watch

199.99

1

Green str. 2

PS3

400

1

Pall Mall, 3

Рис. 8.2. Значение запроса 8.2

Запросы 8.3 и 8.4 иллюстрируют использование логических операций AND и OR.

78

SELECT item, price, quantity, customer_address

 

FROM acceptedorders

 

 

WHERE customer_name = ‘Ms.Magpie’

 

 

AND

item = ‘Book’;

(8.3)

 

 

 

 

 

ITEM

 

PRICE

QUANTITY

CUSTOMER_ADDRESS

Book

 

12.5

1

Pall Mall, 3

Рис. 8.3. Значение запроса 8.3

SELECT item, price, quantity, customer_address

 

FROM acceptedorders

 

 

WHERE customer_name = ‘Ms.Magpie’

 

 

OR item = ‘Book’;

(8.4)

 

 

 

 

 

ITEM

 

PRICE

QUANTITY

CUSTOMER_ADDRESS

Book

 

12.5

1

Pall Mall, 3

Pizza

 

5.5

3

Pall Mall, 3

PS3

 

400

1

Pall Mall, 3

Book

 

12.5

2

Green str. 2

Рис. 8.4. Значение запроса 8.4

Следует отметить, что на практике более типичным является использование запросов с комбинацией условий, накладываемых на различные поля записи, связанных логическими операторами AND, а не операторами OR. Рассмотрим еще одну таблицу и два запроса.

CREATE TABLE Адрес

(Улица CHAR(100),

Дом

CHAR(10),

 

Фамилия

CHAR(100) )

 

 

 

 

 

 

УЛИЦА

ДОМ

ФАМИЛИЯ

 

Садовая

 

10

Ахмедов

 

Лесная

 

2

Кузнецов

 

Садовая

 

10

Ким

 

Садовая

 

3

Кирпичный

 

Школьная

10

Архипов

 

Новая

 

1

Столярова

 

Школьная

1

Школьников

 

Лесная

 

2

Петровский

Рис. 8.5. Таблица «Адрес»

79

SELECT * FROM Адрес

(8.5)

WHERE Улица = ‘Садовая’ AND Дом = ‘10’;

SELECT * FROM Адрес

(8.6)

WHERE Улица = ‘Садовая’ OR Дом = ‘10’

Обратите внимание на использование в именах объектов русских букв; использовать двойные кавычки здесь не обязательно.

Действительно, запрос с использованием OR обладает двумя недостатками:

1.Условие типа «Найти жителей, которые живут на улице Ленина или в доме номер 10» выглядит с логической точки зрения странным.

2.В реальных базах данных в значение подобного запроса попадет большая часть записей исходной таблицы; такие запросы называются запросами с малой селективностью, в отличие от предыдущего запроса, использующего связку условий сравнения на равенство и логический оператор AND, что делает его запросом

с высокой селективностью.

Использование запросов с малой селективностью, скорее всего, свидетельствует о неправильном понимании решаемой задачи или неправильной формулировке запроса.

Рассмотрим еще один типичный пример построения логических выражений. Например, рассмотрим поиск записей, соответствующих словесной формулировке «Найти всех проживающих на улицах Садовой и Школьной». Типичной ошибкой является использование следующего запроса:

SELECT Фамилия FROM Адрес

 

WHERE Улица = ‘Садовая’

(8.7)

AND Улица = ‘Школьная’;

Значением этого запроса, конечно же, всегда будет пустое множество, поскольку одно и то же поле не может быть одновременно равным двум различным значениям. В данном случае связку «и» из словесной формулировки следует интерпретировать как «или на Садовой, или на Школьной». Запрос приобретет правильный вид:

SELECT Фамилия FROM Адрес WHERE Улица = ‘Садовая’

OR Улица

= ‘Школьная’;

(8.8)

80