699
.pdfCURSOR c1 IS SELECT * FROM tbl1; emp_rec2 c1%ROWTYPE;
-Для строки курсора с1,
-созданного из таблицы tbl1 emp_rec3 с1%ROWTYPE;
BEGIN
SELECT * INTO tbl1_rec1 FROM tbl1 WHERE tbl1.f1=1;
emp_rec2:= emp_rec1;
- Присвоение значения всем полям за-
писи
END
Переменная типа «запись» без квалификации именами полей может использоваться только для выборки значений, но ее нельзя применять для вставки или обновления значений строки. В SQL-операторе вставки или обновления для каждого столбца таблицы должно быть указано значение поля записи [14].
Объявление переменной по типу таблицы
CUSTOMERS:
DECLARE
TYPE is_Customers IS TABLE OF CUSTOMERS%ROWTYPE
INDEX BY BINARY_INTEGER; MY_CUST is_Customers;
BEGIN
SELECT * INTO MY_CUST
FROM CUSTOMERS WHERE CUST_NUM = 2108; DBMS_OUTPUT.enable; DBMS_OUTPUT.put_line(TO_CHAR(MY_CUST(
0).CUST_NUM)||' '||MY_CUST(0).COMPANY||' '||
TO_CHAR(MY_CUST(0).CUST_REP)||' '||TO_CHAR(MY_CUST(0).CREDIT_LIMIT));
END;
/
91
В массиве MY_CUST 0 элемент:
{MY_CUST(0).CUST_NUM,MY_CUST(0).COMPA NY,MY_CUST(0).CUST_REP,MY_CUST(0).CREDIT_L IMIT}
{2108,Унесенные ветром,109,55.323}
Другой пример объявления переменной по типу таб-
лицы departments:
DECLARE
dept_rec departments%ROWTYPE; -- declare record
Далее пример присвоения поля dept_rec.department_id переменной v_deptid:
v_deptid:= dept_rec.department_id;
Объявление %ROWTYPE как явного курсора
Если объявить курсор, который извлекает фамилию, оклад, дату найма и работу класса employee, вы можете использовать %ROWTYPE для объявления записи. При выполнении оператора FETCH значение поля last_name из таблицы employees попадает в поле last_name структуры employee_rec, значение столбца salary (зарплата) из таблицы попадает в поле salary структуры employee_rec и
т.д. [12].
DECLARE CURSOR c1 IS
SELECT last_name, salary, hire_date, job_id FROM employees WHERE employee_id = 120;
--declare record variable that
represents a row fetched from the employees table
employee_rec c1%ROWTYPE;
92
BEGIN
-- open the explicit cursor and use it to fetch data into employee_rec
OPEN c1;
FETCH c1 INTO employee_rec; DBMS_OUTPUT.PUT_LINE('Employee name: '
||
employee_rec.last_name);
END;
Подтипы
Язык PL/SQL позволяет определять новые подтипы как подмножество значений некоторого базового типа с тем же набором операций. Подтип не вводит никаких дополнительных операций над данными и не определяет нового типа.
Определение подтипа может иметь следующее формальное описание:
SUBTYPE subtype_name IS base_type;
В пакете STANDARD базы данных Oracle, автоматически подключаемом для любого блока, определено несколько подтипов.
Пользователь может определить свой тип как некоторый подтип в секции объявлений блока, подпрограммы или пакете PL/SQL.
Например:
DECLARE
SUBTYPE MyDate IS DATE;
- Основан на типе DATE
TYPE MyRec IS RECORD (time1 INTEGER, time2 INTEGER);
SUBTYPE MyInterval IS MyRec; - Основан на типе RECORD SUBTYPE ID_N IS tbl1.f1%TYPE;
93
- Основан на типе столбца
Типы, используемые как базовые, не могут содержать ограничений длины. Для создания пользовательского типа с ограничением длины предварительно объявляется переменная такого типа и уже на ее основе определяется пользовательский тип.
Например:
DECLARE
var1 VARCHAR2(6);
-Объявление переменной
-с ограничением длины
SUBTYPE string_6 IS var1%TYPE;
2.2. Преобразование данных
Изменения формата числовых значений в Oracle SQL, функция TO_CHAR для работы с числовыми значениями. Пример запроса, который бы выводил информацию об имени, фамилии и зарплате сотрудников из таблицы hr.employees в
форматеTO_CHAR(SALARY, 'L999999999.99'):
SELECT first_name AS "Имя", last_name As "Фамилия", TO_CHAR(SALARY, 'L999999999.99') As "Оклад" FROM hr.employees ORDER BY SALARY DESC
Результат:
Steven King $24000.15
При этом данные должны быть отсортированы таким образом, чтобы первыми выводились строки для сотрудников с наибольшей зарплатой.
Применение функции NVL
Функция NVL для работы с неопределенными значениями в Oracle SQL. Напишите запрос, который выводит информацию об имени и фамилии сотрудников из таблицы
94
hr.employees, а также ставку комиссии (столбец
COMMISSION_PCT) для сотрудника:
SELECT first_name AS "Имя", last_name As "Фамилия", NVL(COMMISSION_PCT, 0) As "Ставка комиссии" FROM hr.employees
Результат: Trena Rajs 0
John Russell 0.4 [17]
Применение функции DECODE
Функция DECODE для проверки условий в запросах
Oracle SQL
Задание:
Напишите запрос, который возвращает информацию об имени, фамилии и должности сотрудников (столбец JOB_ID) на основе таблицы hr.employees. При этом:
если в столбце JOB_ID для сотрудников находится значение SA_REP, то должно выводиться «Торговый представитель»;
если в столбце JOB_ID для сотрудников находится значение SA_MAN, то должно выводиться «Менеджер по продажам»;
если в этом столбце находится любое другое значение, то должно выводиться «Другое».
SELECT first_name AS "Имя", last_name
As "Фамилия", |
DECODE(JOB_ID, |
'SA_REP', |
|
'Торговый |
представитель', |
'SA_MAN', |
|
'Менеджер |
по |
продажам', 'Другое' ) AS |
|
"Должность" FROM hr.employees |
|
||
Результат: |
|
|
|
Curtis Davies Другое |
продажам |
||
John |
Russell Менеджер по |
||
[17] |
|
|
|
95
Изменение выводимого формата даты
Необходимо представить информацию из таблицы сервера Oracle в соответствии с принятым на предприятии стандартом вывода данных, который выглядит как год/месяц/число, например 2008/02/20. Напишите запрос, который бы выводил из таблицы hr.employees информацию об имени, фамилии и дате приема на работу сотрудников в соответствии с описанным форматом.
SELECT first_name AS "Имя", last_name As "Фамилия", TO_CHAR(HIRE_DATE, 'YYYY/MM/DD') As "Дата приема на работу" FROM hr.employees ORDER BY HIRE_DATE DESC
Amit Banda 2000/04/21 [17]
2.3. Операторы
Операторы – это специальные команды, предназначенные для выполнения простых операций над переменны-
ми [23].
Арифметические операторы: «*» – умножить, «/» – делить, «%» – остаток от деления, «+» – сложить, «–» – вычесть, положительное или отрицательное выражение, «()» – скобки. Операции внутри скобок выполняются в первую очередь.
…WHERE QTYSOLD=-1
Операторы сравнения: «=» – равно, «>» – больше, – меньше, «>=» – больше или равно, «<=» меньше или равно, «<>» («!=») – не равно.
IN «Равен любому члену из списка»
...WHERE JOB IN ('CLERK','ANALIST')
Эквивалентен "=ANY"
96
...WHERE SAL = ANY (SELECT SAL FROM EMP WHERE DEPTNO=30)
NOT IN Эквивалентен "!=ALL"
ANY Сравнивает значение с каждым значением из списка или запроса. Должен предваряться:
=,!=,>,<,<=,>=.
...WHERE SAL=ANY (SELECT SAL FROM EMP WHERE DEPTNO=30)
ALL Сравнивает значение со всеми значениями из списка или запроса. Должен предваряться:
=,!=,>,<,<=,>=.
...WHERE (SAL,COMM)>=ALL ((1400,300),(3000,0))
[NOT] BETWEEN x AND y [Не] больше или рав-
но x и меньше или равно y.
WHERE A BETWEEN 1 AND 9
[NOT] EXISTS TRUE, если запрос возвращает [не возвращает] как минимум одну строку
WHERE EXISTS (SELECT SAL FROM EMP WHERE DEPTNO=30)
[NOT] LIKE «не сопоставляется/сопоставляется со следующим шаблоном». Символ «%» используется для сопоставления с любой строкой из нуля или более символов, кроме NULL – строки, а «_» сопоставляется с любым одиночным символом.
IS [NOT] NULL «проверка на [не] null». IS должен использоваться для проверки на NULL.
WHERE JOB IS NULL
97
Операторы соединения: «+», «||» – соединение (конкатенация) строк.
SELECT 'NAME IS'||ENAME
Логические операторы: «AND» – и, «OR» – или, «NOT» – не.
Операторы со множествами «IN»:
UNION – объединяет запросы для выдачи всех различающихся строк каждого отдельного запроса:
SELECT...UNION SELECT...;
INTERSECT – объединяет запросы для выдачи всех различающихся строк обоих запросов:
SELECT: INTERSECT SELECT...;
MINUS – объединяет запросы для выдачи всех различающихся строк, выданных первым запросом, но не вторым:
...SELECT...MINUS SELECT..
Другие операции
(+) Указывает, что предыдущий столбец – столбец внешнего объединения:
WHERE DEPT.DEPTNO=EMP.DEPTNO(+)
[table.]* Выбирает в запросе все столбцы из таблиц. Когда предваряется именем таблицы с точкой, запрос выбирает все столбцы этой таблицы.
SELECT * FROM EMP SELECT EMP.* FROM EMP
COUNT(expr) Возвращает число строк, в которых expr
не null…
SELECT COUNT(COMM) FROM EMP
COUNT(*) Возвращает число строк в таблице, включая содержащие null…
SELECT COUNT(*) FROM EMP
98
ALL Возвращает дублирующиеся значения в запросах и агрегатах (ALL – умалчиваемое в отличие от DISTINCT).
SELECT ALL *...
...COUNT(ALL DEPTNO)
DISTINCT Удаляет дублирующиеся строки из запроса или удаляет дублирующиеся значения из агрегатного вы-
ражения.
SELECT DISTINCT *...
...COUNT(DISTINCT DEPTNO)...
PRIOR Определяет отношение «отец – сын» в древовидном запросе. Выражение в левой части условия (EMPNO) представляет родительскую строку; выражение справа (MGR) представляет строку ребенка. Может использоваться в любой фразе древовидного запроса, а не только в
CONNECT BY.
CONNECT BY PRIOR EMPNO=MGR
Операция LIKE
Назначение используется при сравнении символьных строк с помощью шаблонов.
Where ENAME LIKE 'BL%' [23]
2.4. Комментарии
Комментарии используются для создания пояснений для блоков сценариев, а также временного отключения команд при отладке скрипта. Комментарии бывают как строковыми, так и блоковыми:
-- – строковый комментарий исключает из выполнения только одну строку, перед которой стоят два минуса.
IF price>100 THEN |
-- |
процедура |
|
Sum_price |
(5); |
sum_price понижает прайсовую стоимость --всех товаров на 5%
END IF;
99
/* */ – блоковый комментарий исключает из выполнения целый блок команд, заключенный в указанную конструкцию.
/* Эта процедура предназначена для выгрузки и данных в EXCEL и обратно
Файл источник - Out.xls Файл приемник - In.xls
Выполнение этой процедуры требует на-
личие Microsoft Excel*/ DECLARE
BEGIN
END;
2.5. Системные функции
Агрегативные функции – функции, которые работают с коллекциями значений и выдают одно значение.
AVG – среднее значение столбца
SUM – сумма значений столбца COUNT – количество элементов столбца. MAX – максимальное значение столбца MIN – минимальное значение столбца
Каковы наибольший и наименьший плановые объемы продаж:
SELECT MIN(QUOTA), MAX(QUOTA) FROM SALESREPS
Скалярные функции – это функции, которые возвращают одно значение, работая со скалярными данными или вообще без входных данных: символьные, преобразования, даты-времени и другие функции, например:
DATEDIFF – разница между датами, ABS – модуль числа, DB_NAME – имя базы данных, USER_NAME – имя текущего пользователя, LEFT – часть строки слева.
100