本文为2 Day Developer's Guide 第2章 Connecting to Oracle Database and Exploring It 的笔记。
您只能通过 SQL*Plus 或 SQL Developer 等客户端程序连接到 Oracle 数据库。 当连接到数据库时,您可以查看模式对象、查看 Oracle 数据库表的属性和数据,以及使用查询从 Oracle 数据库表中检索数据。
通过客户端程序连接到 Oracle 数据库后,您可以在该客户端程序中输入并运行命令。 有关详细信息,请参阅客户端程序的文档。
2.1 从SQL*Plus连接到Oracle数据库
SQL*Plus 是一个客户端程序,您可以从中访问 Oracle 数据库。 本主题介绍如何启动 SQL*Plus 并连接到 Oracle 数据库。
过程略。
2.2 从SQL Developer连接到Oracle数据库
SQL Developer 是一个客户端程序,您可以使用它访问 Oracle 数据库。
我们鼓励您使用当前可用的 SQL Developer 版本,您可以从以下位置下载该版本:
过程略。就提一点,SQL Developer需要JDK,可以用自己的,也可以下载打包了JDK的SQL Developer。
2.3 以用户HR身份连接到Oracle数据库
2.3.1 解锁HR账户
您必须解锁 HR 帐户并重置其密码,然后才能以用户 HR 身份连接到 Oracle 数据库。
sql
ALTER USER HR ACCOUNT UNLOCK IDENTIFIED BY password;
默认情况下,在安装 HR 模式时,HR 帐户被锁定且其密码已过期。
随数据库安装的HR模式需要解锁,但数据库安装完成后,再安装Sample Schema则不需要
2.3.2 以用户HR从SQL*Plus连接到Oracle数据库
略。
2.3.3 以用户HR从SQL Developer连接到Oracle数据库
略。
2.4 用SQL*Plus探索Oracle数据库
如果您作为用户 HR 从 SQL*Plus 连接到 Oracle 数据库,您可以查看 HR 模式对象和 EMPLOYEES 表的属性。
2.4.1 使用SQL*Plus查看HR模式对象
使用 SQL*Plus,您可以通过查询静态数据字典视图 USER_OBJECTS 来查看属于 HR 模式的对象。
与静态数据字典相关的另一个概念是动态视图。
sql
COLUMN OBJECT_NAME FORMAT A25
COLUMN OBJECT_TYPE FORMAT A25
SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS
ORDER BY OBJECT_TYPE, OBJECT_NAME;
USER_视图是用户拥有的,ALL_视图是用户可以看到的,DBA_视图是所有的。如果你是DBA,ALL_和DBA_就是一样的。
2.4.2 使用SQL*Plus查看EMPLOYEES 表属性和数据
您可以通过 SQL*Plus 命令、SQL SELECT 语句和静态数据字典视图来查看 HR.EMPLOYEES 表的属性和数据。
您可以使用 SQL*Plus 命令 DESCRIBE 查看 HR 模式中 EMPLOYEES 表的列的属性,并使用 SQL 语句 SELECT 查看数据。 要查看表的其他属性,请使用静态数据字典视图(例如,USER_CONSTRAINTS、USER_INDEXES 和 USER_TRIGGERS)。
sql
-- 看定义
DESCRIBE EMPLOYEES
-- 看数据
COLUMN FIRST_NAME FORMAT A20
COLUMN LAST_NAME FORMAT A25
COLUMN PHONE_NUMBER FORMAT A20
SELECT LAST_NAME, FIRST_NAME, PHONE_NUMBER FROM EMPLOYEES
ORDER BY LAST_NAME;
2.5 用SQL Developer探索Oracle数据库
此节均略。
2.5.1 教程:使用SQL Developer查看HR模式对象
2.5.2 教程:使用SQL Developer查看EMPLOYEES表属性和数据
2.6 选择表数据
2.6.1 关于查询
查询或 SQL SELECT 语句从一个或多个表或视图中选择数据。
sql
SELECT select_list FROM source_list
select_list 指定要从中选择数据的列,source_list 指定具有这些列的表或视图。
嵌套在另一个 SQL 语句中的查询称为子查询。
在 SQL*Plus 环境中,您可以在 SQL> 提示后输入查询(或任何其他 SQL 语句)。
在 SQL Developer 环境中,您可以在工作表中输入查询(或任何其他 SQL 语句)。
注意:显示查询结果时,记录可能按任意顺序排列,除非您使用 ORDER BY 子句指定它们的顺序。
2.6.2 在SQL Developer中运行查询
略。
2.6.3 教程:选择表的所有列
sql
SELECT * FROM EMPLOYEES;
2.6.4 教程:选择表的特定列
称为projection。
sql
SELECT FIRST_NAME, LAST_NAME, DEPARTMENT_ID FROM EMPLOYEES;
SELECT FIRST_NAME "Given Name", LAST_NAME "Family Name" FROM EMPLOYEES;
2.6.5 在新标题下显示所选列
在显示的查询结果中,默认的列标题是列名。 要在新标题下显示列,请在列名后立即指定新标题(别名)。 别名在查询期间重命名该列,但不会更改其在数据库中的名称。
如果将列别名括在双引号中,则会保留大小写,并且别名可以包含空格。如果没有双引号则为大写。
sql
SELECT FIRST_NAME First, LAST_NAME last, DEPARTMENT_ID DepT
FROM EMPLOYEES;
2.6.6 选择满足指定条件的数据
称为filtering。
要仅选择与指定条件匹配的数据,请在 SELECT 语句中包含 WHERE 子句。
WHERE 子句中的条件可以是任何 SQL 条件(有关 SQL 条件的信息,请参阅 Oracle 数据库 SQL 语言参考 )。
sql
-- IN Condition
WHERE DEPARTMENT_ID IN (100, 110, 120);
-- Pattern-matching Conditions
WHERE LAST_NAME LIKE '%ma%';
-- Comparison Conditions
WHERE DEPARTMENT_ID = 90;
-- Compound Conditions (Comparison Conditions + Null Conditions)
WHERE (SALARY >= 11000) AND (COMMISSION_PCT IS NOT NULL);
2.6.7 对所选数据进行排序
显示查询结果时,记录可以为任何顺序,除非您使用 ORDER BY 子句指定它们的顺序。
或者,在 SQL Developer 中,您可以省略 ORDER BY 子句并双击列名进行排序。
sql
-- Example 2-10 Sorting Selected Data by LAST_NAME
SELECT FIRST_NAME, LAST_NAME, HIRE_DATE
FROM EMPLOYEES
ORDER BY LAST_NAME;
-- Example 2-11 Sorting Selected Data by an Unselected Column
SELECT FIRST_NAME, HIRE_DATE
FROM EMPLOYEES
ORDER BY LAST_NAME;
2.6.8 从多个表中选择数据
要从多个表中选择数据,您可以使用称为连接(Join)的查询。 连接中的表必须至少共享一个列名 。 否则就是笛卡尔连接
假设您要选择每位员工的 FIRST_NAME、LAST_NAME 和 DEPARTMENT_NAME。 FIRST_NAME 和 LAST_NAME 在 EMPLOYEES 表中,DEPARTMENT_NAME 在 DEPARTMENTS 表中。 两个表都有 DEPARTMENT_ID。
表名限定符对于仅出现在连接的一个表中的列名是可选的,但对于同时出现在两个表中的列名是必需的。
例如,以下两个查询是等效的:
sql
SELECT FIRST_NAME "First",
LAST_NAME "Last",
DEPARTMENT_NAME "Dept. Name"
FROM EMPLOYEES, DEPARTMENTS
WHERE EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
ORDER BY DEPARTMENT_NAME, LAST_NAME;
SELECT EMPLOYEES.FIRST_NAME "First",
EMPLOYEES.LAST_NAME "Last",
DEPARTMENTS.DEPARTMENT_NAME "Dept. Name"
FROM EMPLOYEES, DEPARTMENTS
WHERE EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
ORDER BY DEPARTMENTS.DEPARTMENT_NAME, EMPLOYEES.LAST_NAME;
要使使用限定列名的查询更具可读性,请使用表别名:
sql
SELECT FIRST_NAME "First",
LAST_NAME "Last",
DEPARTMENT_NAME "Dept. Name"
FROM EMPLOYEES e, DEPARTMENTS d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
ORDER BY d.DEPARTMENT_NAME, e.LAST_NAME;
虽然您在 FROM 子句中创建了别名,但您可以在查询的前面使用它们:
sql
SELECT e.FIRST_NAME "First",
e.LAST_NAME "Last",
d.DEPARTMENT_NAME "Dept. Name"
FROM EMPLOYEES e, DEPARTMENTS d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID
ORDER BY d.DEPARTMENT_NAME, e.LAST_NAME;
2.6.9 在查询中使用运算符和函数
查询的 select_list 可以包含 SQL 表达式,它可以包含 SQL 运算符和 SQL 函数。 这些运算符和函数可以将表数据作为操作数(operands )和参数。 SQL 表达式被计算,它们的值出现在查询结果中。
2.6.9.1 在查询中使用算术运算符
基本算术运算符------+(加法)、-(减法)、*(乘法)和 /(除法)------对列值进行运算。
sql
SELECT LAST_NAME,
SALARY "Monthly Pay",
SALARY * 12 "Annual Pay"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 90
ORDER BY SALARY DESC;
2.6.9.2 在查询中使用数值函数
数值函数接受数值输入并返回数值。 每个数值函数为计算的每一行返回一个值。
SQL 支持的数字函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
sql
-- 示例 2-14 舍入数值数据
SELECT LAST_NAME,
ROUND (((SALARY * 12)/365), 2) "Daily Pay"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY LAST_NAME;
-- 示例 2-15 截断数值数据
SELECT LAST_NAME,
TRUNC ((SALARY * 12)/365) "Daily Pay"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY LAST_NAME;
2.6.9.3 在查询中使用拼接运算符
拼接运算符 (||) 通过将第二个字符串附加到第一个字符串,将两个字符串组合成一个字符串。 例如,'a'||'b'='ab'。
您可以使用此运算符将来自查询结果的两列的信息或来自同一列中的表达式信息进行合并。
sql
-- 示例 2-16 连接字符数据
SELECT FIRST_NAME || ' ' || LAST_NAME "Name"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY LAST_NAME;
2.6.9.4 在查询中使用字符函数
字符函数接受字符输入。 大多数返回字符值,但有些返回数值。 每个字符函数为计算的每一行返回一个值。
SQL 支持的字符函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
sql
SELECT UPPER(LAST_NAME) "Last",
INITCAP(FIRST_NAME) "First",
LOWER(EMAIL) "E-Mail"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY EMAIL;
2.6.9.5 在查询中使用日期时间函数
日期时间函数对 DATE、时间戳和间隔值进行操作。 每个日期时间函数为计算的每一行返回一个值。
SQL 支持的日期时间函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
对于每个 DATE 和时间戳值,Oracle 数据库存储以下信息:
- 年
- 月
- 日
- 时
- 分
- 秒
对于每个时间戳值,Oracle 数据库还存储秒的小数部分,您可以指定其精度。 要同时存储时区,请使用数据类型 TIMESTAMP WITH TIME ZONE 或 TIMESTAMP WITH LOCAL TIME ZONE。
有关 DATE 数据类型的更多信息,请参阅 Oracle 数据库 SQL 语言参考 。
有关 TIMESTAMP 数据类型的更多信息,请参阅 Oracle 数据库 SQL 语言参考 。
有关其他时间戳数据类型和间隔数据类型的信息,请参阅Oracle 数据库 SQL 语言参考 。
示例 2-18 中的查询使用 EXTRACT 和 SYSDATE 函数来显示部门 100 中的每个员工受雇了多少年。 SYSDATE 函数返回系统时钟的当前日期作为 DATE 值。
sql
SELECT LAST_NAME,
(EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM HIRE_DATE)) "Years Employed"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY "Years Employed";
如果是同一年不同日期,相减结果会为0:
sql
EODA@PDB1> select sysdate from dual;
SYSDATE
---------
28-MAR-23
EODA@PDB1> select sysdate+1 from dual;
SYSDATE+1
---------
29-MAR-23
示例 2-19 中的查询使用 SYSTIMESTAMP 函数来显示当前系统日期和时间。 SYSTIMESTAMP 函数返回一个 TIMESTAMP 值。
sql
SELECT EXTRACT(HOUR FROM SYSTIMESTAMP) || ':' ||
EXTRACT(MINUTE FROM SYSTIMESTAMP) || ':' ||
ROUND(EXTRACT(SECOND FROM SYSTIMESTAMP), 0) || ', ' ||
EXTRACT(MONTH FROM SYSTIMESTAMP) || '/' ||
EXTRACT(DAY FROM SYSTIMESTAMP) || '/' ||
EXTRACT(YEAR FROM SYSTIMESTAMP) "System Time and Date"
FROM DUAL;
有个时区的问题?
参考:https://database-heartbeat.com/2021/09/28/sysdate-vs-current_date-in-oracle-database/
SQL Developer连接OCI上的DBCS示例:
sql
alter session set NLS_DATE_FORMAT='MM-DD-YYYY HH24:MI:SS';
set lines 300
col sysdate for a25
col current_date for a25
col systimestamp for a40
col current_timestamp for a40
select sysdate, current_date from dual;
select systimestamp, current_timestamp from dual;
输出为:
sql
SYSDATE CURRENT_DATE
------------------------- -------------------------
03-28-2023 03:44:51 03-28-2023 11:44:51
SYSTIMESTAMP CURRENT_TIMESTAMP
---------------------------------------- ----------------------------------------
28-MAR-23 03.44.51.231736000 AM GMT 28-MAR-23 11.44.51.231740000 AM ASIA/SHA
NGHAI
参考4.9 Setting the Database Time Zone
Database Time Zone请保持为默认UTC。
The database time zone is relevant only for TIMESTAMP WITH LOCAL TIME ZONE columns. Oracle recommends that you set the database time zone to UTC (0:00) to avoid data conversion and improve performance when data is transferred among databases. This is especially important for distributed databases, replication, and exporting and importing.
sql
EODA@PDB1> ALTER DATABASE SET TIME_ZONE='-05:00';
ALTER DATABASE SET TIME_ZONE='-05:00'
*
ERROR at line 1:
ORA-30079: cannot alter database timezone when database has TIMESTAMP WITH LOCAL TIME ZONE columns
2.6.9.6 在查询中使用转换函数
转换函数将一种数据类型转换为另一种数据类型。
SQL 支持的转换函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
示例 2-20 中的查询使用 TO_CHAR 函数将 HIRE_DATE 值(属于 DATE 类型)转换为格式为 FMMonth DD YYYY 的字符值。 FM 从月份名称中删除前导和尾随空白。 FMMonth DD YYYY 是日期时间格式模型的示例。 有关日期时间格式模型的信息,请参阅 Oracle 数据库 SQL 语言参考 。
示例 2-21 中的查询使用 TO_NUMBER 函数将 POSTAL_CODE 值(类型为 VARCHAR2)转换为 NUMBER 类型的值,用于计算。
也可以看看:
关于 NLS_DATE_FORMAT 参数
示例 2-20 使用格式模板将日期转换为字符
sql
SELECT LAST_NAME,
HIRE_DATE,
TO_CHAR(HIRE_DATE, 'FMMonth DD YYYY') "Date Started"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY LAST_NAME;
LAST_NAME HIRE_DATE Date Started
------------------------- --------- --------------------------------------------
Chen 28-SEP-05 September 28 2005
Faviet 16-AUG-02 August 16 2002
Greenberg 17-AUG-02 August 17 2002
Popp 07-DEC-07 December 7 2007
Sciarra 30-SEP-05 September 30 2005
Urman 07-MAR-06 March 7 2006
6 rows selected.
示例 2-21 将字符转换为数字
sql
SELECT CITY,
POSTAL_CODE "Old Code",
TO_NUMBER(POSTAL_CODE) + 1 "New Code"
FROM LOCATIONS
WHERE COUNTRY_ID = 'US'
ORDER BY POSTAL_CODE;
CITY Old Code New Code
------------------------------ ------------ ----------
Southlake 26192 26193
South Brunswick 50090 50091
Seattle 98199 98200
South San Francisco 99236 99237
2.6.9.7 在查询中使用聚合函数
聚合函数采用一组行并返回单个结果行。 行组可以是整个表或视图。
SQL 支持的聚合函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
聚合函数在与 GROUP BY 子句一起使用时特别强大,该子句按一个或多个列对查询结果进行分组,每组都有一个结果。
示例 2-22 中的查询使用 COUNT 函数和 GROUP BY 子句来显示向每个经理报告的人数。
示例 2-22 显示一名员工不向经理报告。
sql
COLUMN FIRST_NAME FORMAT A10;
COLUMN LAST_NAME FORMAT A10;
COLUMN JOB_TITLE FORMAT A10;
SELECT e.FIRST_NAME,
e.LAST_NAME,
j.JOB_TITLE
FROM EMPLOYEES e, JOBS j
WHERE e.JOB_ID = j.JOB_ID
AND MANAGER_ID IS NULL;
FIRST_NAME LAST_NAME JOB_TITLE
---------- ---------- ----------
Steven King President
要使查询仅返回聚合值满足指定条件的行,请在查询的 HAVING 子句中使用聚合函数。
示例 2-23 中的查询显示了每个部门每年在工资上的花费,但仅限于该金额超过 1,000,000 美元的部门。
示例 2-24 中的查询使用多个聚合函数来显示每个 JOB_ID 的薪水统计信息。
示例 2-22 计算每组中的行数
sql
SELECT MANAGER_ID "Manager",
COUNT(*) "Number of Reports"
FROM EMPLOYEES
GROUP BY MANAGER_ID
ORDER BY MANAGER_ID;
Manager Number of Reports
---------- -----------------
100 14
101 5
102 1
103 4
108 5
114 5
120 8
121 8
122 8
123 8
124 8
145 6
146 6
147 6
148 6
149 6
201 1
205 1
1
19 rows selected.
示例 2-23 将聚合函数限制为满足条件的行
sql
SELECT DEPARTMENT_ID "Department",
SUM(SALARY*12) "All Salaries"
FROM EMPLOYEES
HAVING SUM(SALARY * 12) >= 1000000
GROUP BY DEPARTMENT_ID;
Department All Salaries
---------- ------------
50 1876800
80 3654000
示例 2-24 使用聚合函数获取统计信息
sql
SELECT JOB_ID,
COUNT(*) "#",
MIN(SALARY) "Minimum",
ROUND(AVG(SALARY), 0) "Average",
MEDIAN(SALARY) "Median",
MAX(SALARY) "Maximum",
ROUND(STDDEV(SALARY)) "Std Dev"
FROM EMPLOYEES
GROUP BY JOB_ID
ORDER BY JOB_ID;
JOB_ID # Minimum Average Median Maximum Std Dev
---------- ---------- ---------- ---------- ---------- ---------- ----------
AC_ACCOUNT 1 8300 8300 8300 8300 0
AC_MGR 1 12008 12008 12008 12008 0
AD_ASST 1 4400 4400 4400 4400 0
AD_PRES 1 24000 24000 24000 24000 0
AD_VP 2 17000 17000 17000 17000 0
FI_ACCOUNT 5 6900 7920 7800 9000 766
FI_MGR 1 12008 12008 12008 12008 0
HR_REP 1 6500 6500 6500 6500 0
IT_PROG 5 4200 5760 4800 9000 1926
MK_MAN 1 13000 13000 13000 13000 0
MK_REP 1 6000 6000 6000 6000 0
PR_REP 1 10000 10000 10000 10000 0
PU_CLERK 5 2500 2780 2800 3100 239
PU_MAN 1 11000 11000 11000 11000 0
SA_MAN 5 10500 12200 12000 14000 1525
SA_REP 30 6100 8350 8200 11500 1524
SH_CLERK 20 2500 3215 3100 4200 548
ST_CLERK 20 2100 2785 2700 3600 453
ST_MAN 5 5800 7280 7900 8200 1066
19 rows selected.
2.6.9.8 在查询中使用NULL相关函数
NULL 相关函数有助于处理 NULL 值。
SQL 支持的 NULL 相关函数在 Oracle 数据库 SQL 语言参考 中列出和描述。
示例 2-25 中的查询返回姓氏以"B"开头的员工的姓氏和佣金。 如果员工没有收到佣金(即,如果 COMMISSION_PCT 为 NULL),则 NVL 函数用"Not Applicable"替换 NULL。
示例 2-26 中的查询使用 NVL2 函数返回姓氏以 'B' 开头的员工的姓氏、薪水和收入: 如果 COMMISSION_PCT 不为 NULL,则收入为薪水加上佣金; 如果 COMMISSION_PCT 为 NULL,则收入仅为工资。
示例 2-25 用字符串替换 NULL 值
sql
SELECT LAST_NAME,
NVL(TO_CHAR(COMMISSION_PCT), 'Not Applicable') "COMMISSION"
FROM EMPLOYEES
WHERE LAST_NAME LIKE 'B%'
ORDER BY LAST_NAME;
LAST_NAME COMMISSION
---------- ----------------------------------------
Baer Not Applicable
Baida Not Applicable
Banda .1
Bates .15
Bell Not Applicable
Bernstein .25
Bissot Not Applicable
Bloom .2
Bull Not Applicable
9 rows selected.
示例 2-26 为 NULL 值和 Not NULL 值指定不同的表达式
sql
SELECT LAST_NAME, SALARY,
NVL2(COMMISSION_PCT, SALARY + (SALARY * COMMISSION_PCT), SALARY) INCOME
FROM EMPLOYEES WHERE LAST_NAME LIKE 'B%'
ORDER BY LAST_NAME;
LAST_NAME SALARY INCOME
---------- ---------- ----------
Baer 10000 10000
Baida 2900 2900
Banda 6200 6820
Bates 7300 8395
Bell 4000 4000
Bernstein 9500 11875
Bissot 3300 3300
Bloom 10000 12000
Bull 4100 4100
9 rows selected.
2.6.9.9 在查询中使用CASE表达式
CASE 表达式允许您在 SQL 语句中使用 IF ... THEN ... ELSE 逻辑,而无需调用子程序。 有两种 CASE 表达式,简单的和搜索的。
示例 2-27 中的查询使用一个简单的 CASE 表达式来显示每个国家代码的国家名称。
示例 2-28 中的查询使用搜索 CASE 表达式来显示建议的加薪幅度(15%、10%、5% 或 0%),基于与服务年限相关的日期范围。
示例 2-27 在查询中使用简单的 CASE 表达式
sql
SELECT UNIQUE COUNTRY_ID ID,
CASE COUNTRY_ID
WHEN 'AU' THEN 'Australia'
WHEN 'BR' THEN 'Brazil'
WHEN 'CA' THEN 'Canada'
WHEN 'CH' THEN 'Switzerland'
WHEN 'CN' THEN 'China'
WHEN 'DE' THEN 'Germany'
WHEN 'IN' THEN 'India'
WHEN 'IT' THEN 'Italy'
WHEN 'JP' THEN 'Japan'
WHEN 'MX' THEN 'Mexico'
WHEN 'NL' THEN 'Netherlands'
WHEN 'SG' THEN 'Singapore'
WHEN 'UK' THEN 'United Kingdom'
WHEN 'US' THEN 'United States'
ELSE 'Unknown'
END COUNTRY
FROM LOCATIONS
ORDER BY COUNTRY_ID;
ID COUNTRY
-- --------------
AU Australia
BR Brazil
CA Canada
CH Switzerland
CN China
DE Germany
IN India
IT Italy
JP Japan
MX Mexico
NL Netherlands
SG Singapore
UK United Kingdom
US United States
14 rows selected.
示例 2-28 在查询中使用搜索 CASE 表达式
sql
SELECT LAST_NAME "Name",
HIRE_DATE "Started",
SALARY "Salary",
CASE
WHEN HIRE_DATE < TO_DATE('01-Jan-03', 'dd-mon-yy')
THEN TRUNC(SALARY*1.15, 0)
WHEN HIRE_DATE >= TO_DATE('01-Jan-03', 'dd-mon-yy') AND
HIRE_DATE < TO_DATE('01-Jan-06', 'dd-mon-yy')
THEN TRUNC(SALARY*1.10, 0)
WHEN HIRE_DATE >= TO_DATE('01-Jan-06', 'dd-mon-yy') AND
HIRE_DATE < TO_DATE('01-Jan-07', 'dd-mon-yy')
THEN TRUNC(SALARY*1.05, 0)
ELSE SALARY
END "Proposed Salary"
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 100
ORDER BY HIRE_DATE;
Name Started Salary Proposed Salary
------------------------- --------- ---------- ---------------
Faviet 16-AUG-02 9000 10350
Greenberg 17-AUG-02 12008 13809
Chen 28-SEP-05 8200 9020
Sciarra 30-SEP-05 7700 8470
Urman 07-MAR-06 7800 8190
Popp 07-DEC-07 6900 6900
6 rows selected.
2.6.9.10 在查询中使用DECODE函数
DECODE 函数将一个表达式与多个搜索值进行比较。 只要表达式的值与搜索值匹配,DECODE 就会返回与该搜索值关联的结果。 如果 DECODE 找不到匹配项,则返回默认值(如果指定)或 NULL(如果未指定默认值)。
示例 2-29 中的查询使用 DECODE 函数来显示三个不同工作的建议加薪。 表达式为JOB_ID; 搜索值为"PU_CLERK"、"SH_CLERK"和"ST_CLERK"; 默认值是 SALARY。
注意:DECODE 函数的参数可以是任何 SQL 数字或字符类型。 Oracle 在比较之前自动将表达式和每个搜索值转换为第一个搜索值的数据类型。 Oracle 自动将返回值转换为与第一个结果相同的数据类型。 如果第一个结果的数据类型为 CHAR 或者如果第一个结果为 NULL,则 Oracle 将返回值转换为数据类型 VARCHAR2。
示例 2-29 在查询中使用 DECODE 函数
sql
SELECT LAST_NAME, JOB_ID, SALARY,
DECODE(JOB_ID,
'PU_CLERK', SALARY * 1.10,
'SH_CLERK', SALARY * 1.15,
'ST_CLERK', SALARY * 1.20,
SALARY) "Proposed Salary"
FROM EMPLOYEES
WHERE JOB_ID LIKE '%_CLERK'
AND LAST_NAME < 'E'
ORDER BY LAST_NAME;
LAST_NAME JOB_ID SALARY Proposed Salary
---------- ---------- ---------- ---------------
Atkinson ST_CLERK 2800 3360
Baida PU_CLERK 2900 3190
Bell SH_CLERK 4000 4600
Bissot ST_CLERK 3300 3960
Bull SH_CLERK 4100 4715
Cabrio SH_CLERK 3000 3450
Chung SH_CLERK 3800 4370
Colmenares PU_CLERK 2500 2750
Davies ST_CLERK 3100 3720
Dellinger SH_CLERK 3400 3910
Dilly SH_CLERK 3600 4140
11 rows selected.