Oracle 《数据库 2 天开发人员指南》第2章:连接与探索Oracle数据库

本文为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 版本,您可以从以下位置下载该版本:

https://oracle.com/sqldev

过程略。就提一点,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.
相关推荐
曹牧12 小时前
Oracle:计算小数年龄
数据库·oracle
cmcm!15 小时前
做题记录2
数据库·oracle
dingdingfish16 小时前
Oracle 《数据库 2 天开发人员指南》第1章:2天Oracle数据库开发介绍
oracle·database·developer·guide·intro
专注VB编程开发20年17 小时前
最快速度取最新一条数据-Mysql,Sql server,access数据库
数据库·sql·mysql·oracle·sqlserver·access
晴天¥17 小时前
Oracle19c-单机版数据库启动、关闭
数据库·oracle
惜分飞17 小时前
win平台挂起Oracle数据库启动进程
数据库·oracle
宇灬宇17 小时前
oracle RAC加表空间误加入本地空间
数据库·oracle
为中华崛起而奋斗17 小时前
Oracle杀会话流程
数据库·oracle
yong999018 小时前
C# 入门级库存管理系统
jvm·oracle·c#