0
点赞
收藏
分享

微信扫一扫

Oracle 数据库表和视图 的操作

王小沫 2024-06-21 阅读 25

1. 命令方式操作数据库(采用SQL*Plus)

1.1 创建表

1.1.1 基本语法格式

CREATE TABLE[<用户方案名>]<表名>
(
    <列名1> <数据类型> [DEFAULT <默认值>] [<列约束>]
    <列名2> <数据类型> [DEFAULT <默认值>] [<列约束>]
[,...n]
    <表约束>[,...n]
)
    [AS<子查询>]

1.1.2 说明

用户方案名
DEFAULT
列约束

定义一个完整性约束作为列定义的一部分,该子句的语法为:

表约束
AS<子查询>

表示将由子查询返回的行插入到所创建的表中。

示例:

 

1.2 修改表

1.2.1 语法格式

ALTER TABLE <表名>
  ADD (<列定义1>, <列定义2>, ...),
  MODIFY (<列修改1>, <列修改2>, ...),
  DROP (<列名1>, <列名2>, ...);

1.2.2 说明

删除 PRIMARY KEYUNIQUE 约束前的注意事项

 解释:


 

1.3 删除表

1.3.1 语法格式

DROP TABLE[<用户方案名>]<表名>

 

1.4 插入记录

1.4.1 语法格式1

INSERT INTO<表名>[(<列名1)>,(<列名2>,...n)]
    VALUES(<列值1>,<列值2>,...n)
示例:

同样可以使用 INSERT 语句把一个表中的部分数据插入到另一个表中,但结果集中每行数据集的字段数、字段的数据类型要与被操作的表完全一致。

1.4.2 语法格式2

INSERT INTO<表名>
    <结果集>

其中,<结果集>是一个由 SELECT 语句查询所得到的新表。 

如果要将 table1 中的部分数据插入到 table2 中,可以使用以下 SQL 语句:

INSERT INTO table2 (id, name, age)
    SELECT id, name, age
        FROM table1
        WHERE age > 30;
COMMIT;

 

1.5 删除记录

1.5.1 DELETE 语句

DELETE FROM <表名> [WHERE <条件>];

 删除 table1 中所有年龄大于30的记录:

DELETE FROM table1 WHERE age > 30;

1.5.2 TRUNCATE TABLE 语句

如果要删除一个大表里的全部记录,可以用此语句,他可以释放占用的数据块表空间,此操作不可回退。语法格式为:

TRUNCATE TABLE <表名>;

 删除 table1 中所有记录,并释放表空间:

TRUNCATE TABLE table1;

 

1.6 修改记录

UPDATE 语句可以用来修改表总的数据行,语法格式为:

UPDATE<表名>
    SET <列名>={<新值>|<表达式>}[,...n]
    [WHERE <条件表达式>]

示例:

UPDATE XSB
    SET 备注='辅修计算机专业'
    WHERE 学号='15014';
UPDATE a
    SET 总学分=总学分+5;

2. 数据库的查询和视图

2.1 选择、投影、连接

2.1.1 选择

选择(Selection),简单来说就是通过一定条件把自己所需要的数据检索出来。选择是单目运算,其对象是一个表。该运算按给定的条件,从表中选出满足条件的行形成一个新表,作为运算结果。

假设有一个表 Employees,包含以下列:

EmployeeIDFirstNameLastNameAgeDepartment
1JohnDoe30HR
2JaneSmith25IT
3MikeBrown40Sales

如果我们只选择 Age 大于 30 的员工,SQL 查询如下:

SELECT *
    FROM Employees
    WHERE Age > 30;

查询结果为:

EmployeeIDFirstNameLastNameAgeDepartment
3MikeBrown40Sales

2.1.2 投影

投影(Projection)也是单目运算。投影就是选择表中指定的列,这样在查询结果中只显示指定数据列,减少了显示的数据量,也可调高查询的性能。

假设我们仍然使用上面的 Employees 表,如果我们只对 FirstNameDepartment 进行投影,SQL 查询如下:

SELECT FirstName, Department
    FROM Employees;

查询结果为:

FirstNameDepartment
JohnHR
JaneIT
MikeSales

组合投影和选择

我们也可以将投影和选择组合在一起使用。例如,我们想选择 Age 大于 30 的员工,并只显示他们的 FirstNameDepartment,SQL 查询如下:

SELECT FirstName, Department
    FROM Employees
    WHERE Age > 30;

查询结果为:

FirstNameDepartment
MikeSales

表的选择和投影运算分别从行和列两个方向上分割表,而以下要讨论的连接运算则是对两个表的操作。

2.1.3 连接

连接(JOIN)是把两个表的行按照给定的条件进行拼接而形成新表。

  

总结


 

2.2 数据库的查询

SELECT 语句主要的语法格式:

SELECT<列>                                /*指定要选择的列及其限定*/
    FROM <表或视图>                        /*FROM 子句,指定表或视图*/
    [WHERE <条件表达式>]                   /*WHERE 子句,指定查询条件*/ 
    [GROUP BY <分组表达式>]                /*GROUP BY 子句,指定分组表达式*/
    [HAVING <分组条件表达式>]              /*HAVING 子句,指定分组统计条件*/
    [ORDER BY <排序表达式>[ASC|DESC]]      /*ORDER BY 子句,指定排序表达式和顺序*/

下面讨论 SELECT 的基本语法和主要功能。 

2.2.1 选择列

选择表中的列组成结果集,语法格式为:

SELECT [ALL|DISTINCT]<列名列表>
  • ALL:默认行为,返回所有符合条件的行,包括重复行。
  • DISTINCT:只返回唯一的行,去除重复的行。

 其中<列名列表>指出了结果的形式,其主要格式为:

{    *                            /*选择当前表或视图的所有列*/
    |{<表名>|<视图>} *             /*选择指定的表或视图的所有列*/
    |{<列名>|<表达式>.}             
        [[AS}<列别名>]             /*选择指定的列*/
    |<列标题>=<列名表达式>          /*选择指定列并更改列标题*/
}[,...n]
详细解释和示例
1. 选择当前表或视图的所有列
SELECT *
    FROM Employees;

这个语句将选择 Employees 表中的所有列。 


2. 选择指定的表或视图的所有列
SELECT Employees.*
    FROM Employees;

 这个语句也将选择 Employees 表中的所有列,与上面的语句效果相同。


 3. 选择指定的列或表达式
SELECT FirstName, LastName, Age + 5 AS AgePlusFive
    FROM Employees;

这个语句选择 FirstNameLastName 列,并选择一个表达式 Age + 5,同时将其命名为 AgePlusFive


4. 为选定的列或表达式指定别名
SELECT FirstName AS FName, LastName AS LName, Age + 5 AS AgePlusFive
    FROM Employees;

这个语句选择 FirstNameLastName 列,并分别将它们重命名为 FNameLName


 5. 选择指定列或表达式并更改列标题
-- 查询,临时重命名列
SELECT FName = FirstName, LName = LastName
    FROM Employees;

这一改变仅对当前查询有效,并不会对表的实际结构产生影响。 

建议

为了确保 SQL 语句的可移植性和标准化,通常建议使用 AS 来指定别名,除非明确知道目标数据库系统支持 = 并且有特殊的需求。

组合示例

假设我们有一个表 Employees,其结构如下:

EmployeeIDFirstNameLastNameAgeDepartment
1JohnDoe30HR
2JaneSmith25IT
3MikeBrown40Sales

 我们希望选择所有列并且对某些列进行别名处理

SELECT EmployeeID, FirstName AS FName, LastName AS LName, Age + 5 AS AgePlusFive,Department
    FROM Employees;

 查询结果如下:

EmployeeIDFNameLNameAgePlusFiveDepartment
1JohnDoe35HR
2JaneSmith30IT
3MikeBrown45Sales

2.2.2 选择行

WHERE <表达式>

其中,<条件表达式>为查询条件,格式为:

<条件表达式>::=
    { [NOT]<判定运算>|(条件表达式)}
    [{AND|OR} [NOT]{<判定运算>|(条件表达式)}]
    }[,...n]

 其中,<判定运算>的结果为TRUEFALSEUNKNOWN,经常用到的格式为:

<判定运算>::=
{    <表达式1>{=|<|<=|>|>=|<>|!=}<表达式2>        /*比较运算*/
     |<字符串表达式1>[NOT] LIKE<字符串表达式2>[ESCAPE'<转义字符>'] /*字符串匹配模式*/
     |<表达式>[NOT] BETWEEN<表达式1>AND<表达式2>   /*指定范围*/
     |<表达式>IS [NOT] NULL    /* 是否空值判断*/
     |<表达式> [NOT] IN (<子查询>|<表达式>[,...n]) /*IN 子句*/
     |EXIST(<子查询>)                             /*EXIST 子查询*/
}
     

 判定运算包括比较运算、模式匹配、范围比较、空值比较和子查询。

比较时注意限制:

在使用字符串和日期数据进行比较时,注意要符合下面一些限制。

(1)字符串和日期必须是用单引号括起来。

(2)字符串数据区分大小写。

(3)日期数据的格式是敏感的,默认的日期格式是 DD-MM月-YY,可使用 ALTER SESSION 语句将默认日期修改为 YYYY-MM-DD。

SQL> SELECT SYSDATE AS CurrentDateTime
  2  FROM dual;

CURRENTDATETIM
--------------
16-6月 -24

SQL>
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
2.2.2.1 表达式比较
<表达式1>{=|<|<=|>|>=|<>|!=}<表达式2> 
2.2.2.2 模式匹配
<字符串表达式1>[NOT] LIKE<字符串表达式2>
通配符的功能介绍

假设我们有一个表 Employees,其结构如下:

EmployeeIDFirstNameLastNameAgeDepartment
1JohnDoe30HR
2JaneSmith25IT
3MikeBrown40Sales


2.2.2.3 范围比较
2.2.2.4 空值比较

语法格式

<表达式> IS [NOT] NULL
示例:

2.2.2.5 子查询

语法格式

<表达式> {=|<|<=|>|>=|<>|!=} (子查询)
<表达式> [NOT] IN (子查询)
<表达式> [NOT] EXISTS (子查询)
(1)比较子查询 
SELECT EmployeeID, FirstName, LastName, Salary
FROM Employees
WHERE Salary = (SELECT MIN(Salary) 
                FROM Employees 
                WHERE DepartmentID = 10);
(2)IN 子查询 
 示例:

假设我们有两个表 EmployeesDepartments,结构如下:

Employees 表:

EmployeeIDFirstNameLastNameAgeDepartment
1JohnDoe30HR
2JaneSmith25IT
3MikeBrown40Sales

Departments 表:

DepartmentLocation
HRNew York
ITSan Francisco
SalesChicago

我们希望找到 IT 部门的员工: 

SELECT * 
    FROM Employees
    WHERE Department = (SELECT Department FROM Departments WHERE Department = 'IT');

 结果:

EmployeeIDFirstNameLastNameAgeDepartment
2JaneSmith25IT

我们希望找到不在 IT 部门的员工:

SELECT * 
    FROM Employees
    WHERE Department <> (SELECT Department FROM Departments WHERE Department = 'IT');

 结果:

EmployeeIDFirstNameLastNameAgeDepartment
1JohnDoe30HR
3MikeBrown40Sales

注意:IN 和 NOT IN 子查询只能返回一列数据。对于较复杂的查询,可使用嵌套的子查询。 

查询未选修离散数学的学生情况:

SELECT 学号,姓名,专业,总学分
    FROM XSB
    WHERE 学号 NOT IN
        (SELECT 学号
            FROM CJB
            WHERE 课程号 IN
                (SELECT 课程号
                    FROM KCB
                    WHERE 课程号='离散数学'
                    )
        );

(3) EXISTS 子查询

假设我们有以下两个表:

  1. Students 表(学生表),结构如下:
StudentIDNameMajor
1AliceCS
2BobMath
3CharliePhysics
4DavidCS
  1. Enrollments 表(选课表),结构如下:
StudentIDCourseID
1101
2102
3103
4101
1102
示例 1:EXISTS

查询所有选修了 101 课程的学生信息。

SELECT *
FROM Students
WHERE EXISTS (
    SELECT 1
    FROM Enrollments e
    WHERE e.StudentID = s.StudentID AND e.CourseID = 101
);

解释:

  • 外层查询从 Students 表中选择所有学生。
  • 内层子查询从 Enrollments 表中查找 CourseID101 的记录,并且匹配 Students 表中的 StudentID
  • EXISTS 只需检查子查询是否返回任何记录。如果子查询返回至少一条记录,则 EXISTS 返回 TRUE,否则返回 FALSE
  • 最终结果是所有选修了 101 课程的学生。

结果:

StudentIDNameMajor
1AliceCS
4DavidCS
示例 2:NOT EXISTS

查询所有没有选修 101 课程的学生信息。

SELECT *
FROM Students
WHERE NOT EXISTS (
    SELECT 1
    FROM Enrollments e
    WHERE e.StudentID = s.StudentID AND e.CourseID = 101
);

无论子查询中是 SELECT 1SELECT * 还是 SELECT e.CourseID,效果都是相同的,因为 EXISTS 子句只关心子查询是否返回了至少一条记录。 

结果:

StudentIDNameMajor
2BobMath
3CharliePhysics

2.2.3 查询对象

前面介绍了 SELECT 选择表的列和行的操作,这里介绍 SELECT 查询对象(即数据源)的构成形式。

查找与 151101 号同学所选修课程一致的同学的学号:

SELECT DISTINCT 学号
    FROM CJB 成绩1
    WHERE NOT EXISTS
        (SELECT *
            FROM CJB 成绩2
            WHERE 成绩2.学号='151101'AND NOT EXISTS
                (SELECT *
                    FROM CJB 成绩3
                    WHERE 成绩3.学号=成绩1.学号
                        AND 成绩3.课程号=成绩2.课程号
                )
        );

2.2.4 连接

连接是二元运算,可以对两个或多个表进行查询,结果通常是含有参加连接运算的两个(或多个)表指定列的表。

2.2.4.1 连接谓词

可以在 SELECT 语句的 WHERE 子句中使用比较运算符给出连接条件对表进行连接,将这种表现形式称为连接谓词。

SELECT XSB.*,CJB.*
    FROM XSB,CJB
    WHERE XSB.学号=CJB.学号;

若选择的字段名在各个表中是唯一的,则可以省略字段名前的表名。例如:

SELECT XSB.*,CJB.课程号,成绩
    FROM XSB,CJB
    WHERE XSB.学号=CJB.学号;

连接和子查询可能都要涉及两个或多个表,区别是连接可以合并两个或多个表的数据,而带子查询的 SELECT 语句的结果只能来自一个表,子查询的结果是用来作为选择结果数据时进行参照的。

有的查询既可以使用子查询也可以使用连接表达。通常,使用子查询表达式可以将一个复杂的查询分解为一系列逻辑步骤,条理清晰;而使用连接表达有执行速度快的优点。因此,应尽量使用连接表示查询。

2.2.4.2 以 JOIN 关键字指定的连接
连接表的格式:
<表名><连接类型><表名>ON<条件表达式>
|<表名>CROSS JOIN<表名>
|<连接表>

其中,<连接类型>的格式:

<连接类型>::=
    {INNER|{LEFT|RIGHT|FULL} [OUTER] CROSS JOIN

2.2.5 汇总

2.2.6 排序

在 Oracle 中,可以使用 ORDER BY 子句对查询结果进行排序。默认情况下,排序是按升序 (ASC),也可以指定为降序 (DESC)。

示例

按姓氏升序排序

SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY
    FROM EMPLOYEES
ORDER BY LAST_NAME ASC;

 按工资降序排序

SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY
    FROM EMPLOYEES
ORDER BY SALARY DESC;

按姓氏升序、工资降序排序: 

SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY
    FROM EMPLOYEES
ORDER BY LAST_NAME ASC, SALARY DESC;

2.2.7 合并

Oracle 提供了几种合并查询结果的方法,包括 UNION, UNION ALL, INTERSECTMINUS

UNION UNION ALL

  • UNION 用于合并两个查询结果,默认去除重复记录。
  • UNION ALL 也用于合并两个查询结果,但不去除重复记录。

示例

假设有两个表 EMPLOYEESMANAGERS,结构如下:

  • EMPLOYEES: EMPLOYEE_ID, FIRST_NAME, LAST_NAME
  • MANAGERS: MANAGER_ID, FIRST_NAME, LAST_NAME

使用 UNION 合并两个表中的记录

SELECT FIRST_NAME, LAST_NAME 
    FROM EMPLOYEES
UNION
SELECT FIRST_NAME, LAST_NAME 
    FROM MANAGERS;

使用 UNION ALL 合并两个表中的记录

SELECT FIRST_NAME, LAST_NAME 
    FROM EMPLOYEES
UNION ALL
SELECT FIRST_NAME, LAST_NAME 
    FROM MANAGERS;

INTERSECT

  • INTERSECT 返回两个查询的交集,即同时存在于两个查询结果中的记录。

示例

查询员工和经理中都存在的名字

SELECT FIRST_NAME, LAST_NAME 
    FROM EMPLOYEES
INTERSECT
SELECT FIRST_NAME, LAST_NAME 
    FROM MANAGERS;

 MINUS

  • MINUS 返回在第一个查询中存在但在第二个查询中不存在的记录。

示例

查询在员工表中存在但不在经理表中的名字

SELECT FIRST_NAME, LAST_NAME 
    FROM EMPLOYEES
MINUS
SELECT FIRST_NAME, LAST_NAME 
    FROM MANAGERS;

2.3 数据库视图

2.3.1 视图的概念

2.3.2 创建视图

2.3.3 查询视图

视图创建后,可以像查询表一样查询视图。

查询刚刚创建的视图:

SELECT * 
    FROM emp_dept_view;

2.3.4 更新视图

2.3.5 修改视图的定义

可以使用 CREATE OR REPLACE VIEW 语句来修改视图的定义。

CREATE OR REPLACE VIEW <视图名> 
AS
    SELECT <列名>
        FROM <表名>
        WHERE <条件表达式>;

2.3.6 删除视图

DROP VIEW <视图名>;

 

2.4 含替换变量的查询

 Oracle SQL*Plus 提供了使用替换变量的功能,允许用户在运行时输入值,从而提高查询的灵活性。常用的替换变量有单一替换变量(&)、多次替换变量(&&),以及定义和接受命令(DEFINEACCEPT)。

2.4.1 &替换变量

 & 替换变量用于在查询中提示用户输入值。每次执行查询时,用户都会被提示输入一个值。

SELECT * 
    FROM EMPLOYEES 
    WHERE EMPLOYEE_ID = &employee_id;

注意:

替换变量是字符类型或日期类型的数据,输入值必须要用单引号括起来。为了在输入数据是不需要输入单引号,也可以使用在 SELECT 语句中把变量用单引号括起来。

因此,上面的也可以使用如下语句:

SELECT * 
    FROM EMPLOYEES 
    WHERE EMPLOYEE_ID = &'employee_id';

 为了在执行变量替换之前,显示如何执行替换的值,可以使用 SET VERIFY 命令

SET VERIFY ON

 示例:

SQL> SELECT *
  2     FROM EMPLOYEES
  3     WHERE HOURLY_RATE>&HOURLY_RATE;
输入 hourly_rate 的值:  20
原值    3:      WHERE HOURLY_RATE>&HOURLY_RATE
新值    3:      WHERE HOURLY_RATE>20

EMPLOYEE_ID EMPLOYEE_NAME        HOURLY_RATE
----------- -------------------- -----------
          4 Emily                      22.25
          8 Amy                         21.5
          9 Michael                       23
         10 Michelle                   24.75

2.4.2 &&替换变量

 && 替换变量用于多次使用同一个值。用户在第一次输入后,后续的查询中将不会再次提示输入。

查询选修课程超过两门且成绩在75以上的学生的学号:

SELECT &&column
    FROM CJB
    WHERE 成绩>=75
    GROUP BY &column
    HAVING COUNT(*)>2;

 用户输入 学号 后,SQL*Plus 会记住这个值。在同一会话中,再次使用 &&column 时,不会提示用户再次输入。

2.4.3 DEFINE 和 ACCEPT 命令

DEFINE 命令:用于创建一个替换变量,并赋予初始值。DEFINE 命令创建的变量在会话期间有效,直到被显式取消(UNDEFINE)。

DEFINE [<变量名>[=<变量值>]]
使用 DEFINE 变量 
  • 使用 DEFINE 命令

假设我们使用 DEFINE 命令创建一个变量,并为其赋值: 

DEFINE employee_id = 101

 在这个例子中,employee_id 是一个字符类型(CHAR)的变量,尽管它的值看起来像是一个数字。

-- 设置 VERIFY 模式以显示变量替换
SET VERIFY ON;

-- 创建一个字符类型的变量
DEFINE employee_id = 101

-- 使用变量进行查询
SELECT * 
    FROM EMPLOYEES 
    WHERE EMPLOYEE_ID = &employee_id;
使用 UNDEFINE 取消变量

可以使用 UNDEFINE 命令取消已定义的变量,这样下一次使用该变量时会提示用户重新输入值:

-- 取消变量定义
UNDEFINE employee_id

-- 再次提示用户输入变量值
SELECT * 
    FROM EMPLOYEES 
    WHERE EMPLOYEE_ID = &employee_id;
ACCEPT 命令

用于提示用户输入一个值,并将该值赋予一个变量。与 DEFINE 不同的是,ACCEPT 会在执行时提示用户输入。

ACCEPT <变量名> [<数据类型>] [FORMAT<格式模式>]
    [PROMPT <提示文本>] [HIDE]

基本用法

ACCEPT employee_id PROMPT 'Enter Employee ID: '
                                /*输入一个id*/
SELECT * 
    FROM EMPLOYEES 
    WHERE EMPLOYEE_ID = &employee_id;

指定数据类型和格式模式

ACCEPT salary NUMBER FORMAT '99999.99' PROMPT 'Enter Salary: '
                                                /*同上*/
SELECT * 
FROM EMPLOYEES 
WHERE SALARY > &salary;

隐藏输入内容

ACCEPT password CHAR FORMAT 'X' HIDE PROMPT 'Enter Password: '

SELECT *
FROM USERS
WHERE PASSWORD = '&password';

说明:ACCEPT password CHAR FORMAT 'X' HIDE:定义一个名为 password 的字符变量,指定格式模式为 'X'(隐藏输入内容),并且输入时不显示用户输入内容。

 


本篇分享到此为止,感谢支持~🌹 

举报

相关推荐

0 条评论