数据库(3) | Oralce SQL 数据处理

作者: 厲铆兄 | 来源:发表于2016-04-24 13:03 被阅读296次

    SQL语言处理

    本章,我们将会重点探讨SQL语言基础,学习用SQL进行数据库的数据增加、删除和修改等操作。另外请注意本章的SQL语法基于Oracle数据库的PL/SQL语法。

    表的数据操作

    DML 可以在下列条件下执行:

    • 向表中插入数据
    • 修改现存数据
    • 删除现存数据

    新增

    使用 INSERT 语句向表中插入数据。

    处理语法

    INSERT INTO table [(column [, column...])]
    VALUES      (value [, value...]);
    --使用这种语法一次只能向表中插入一条数据。
    
    • 为每一列添加一个新值。
    • 按列的默认顺序列出各个列的值。
    • 在 INSERT 子句中随意列出列名和他们的值。
    • 字符和日期型数据应包含在单引号中。

    插入空值

    隐式方式: 在列名表中省略该列的值。

    INSERT INTO HR.DEPARTMENTS
      (DEPARTMENT_ID, DEPARTMENT_NAME)
    VALUES
      (330, 'Purchasing');
    --1 row created.
    

    显示方式: 在VALUES 子句中指定空值。

    INSERT INTO HR.DEPARTMENTS VALUES (400, 'Finance', NULL, NULL);
    --1 row created.
    

    插入系统时间

    SYSDATE 记录当前系统的日期和时间。

    INSERT INTO HR.EMPLOYEES
      (EMPLOYEE_ID,
       FIRST_NAME,
       LAST_NAME,
       EMAIL,
       PHONE_NUMBER,
       HIRE_DATE,
       JOB_ID,
       SALARY,
       COMMISSION_PCT,
       MANAGER_ID,
       DEPARTMENT_ID)
    VALUES
      (113,
       'Louis',
       'Popp',
       'LPOPP',
       '515.124.4567',
       SYSDATE,
       'AC_ACCOUNT',
       6900,
       NULL,
       205,
       100);
    --1 row created.
    
    INSERT INTO HR.EMPLOYEES
    VALUES
      (114,
       'Den',
       'Raphealy',
       'DRAPHEAL',
       '515.127.4561',
       TO_DATE('FEB 3, 1999', 'MON DD, YYYY'),
       'AC_ACCOUNT',
       11000,
       NULL,
       100,
       30);
    --1 row created.
    

    插入其他表的数据

    INSERT INTO SALES_REPS
      (ID, NAME, SALARY, COMMISSION_PCT)
      SELECT EMPLOYEE_ID, LAST_NAME, SALARY, COMMISSION_PCT
        FROM EMPLOYEES
       WHERE JOB_ID LIKE '%REP%';
    --4 rows created.
    

    更新

    使用 UPDATE 语句更新数据。

    语法示例

    UPDATE      table
    SET     column = value [, column = value, ...]
    [WHERE      condition];
    --可以一次更新多条数据
    

    使用 WHERE 子句指定需要更新的数据。

    UPDATE HR.EMPLOYEES 
    SET DEPARTMENT_ID = 70 
    WHERE EMPLOYEE_ID = 113;
    --1 row updated.
    --如果省略WHERE子句,则表中的所有数据都将被更新。
    

    在UPDATE语句中使用子查询

    UPDATE HR.EMPLOYEES
       SET JOB_ID =
           (SELECT JOB_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 205),
           SALARY =
           (SELECT SALARY FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 205)
     WHERE EMPLOYEE_ID = 114;
    --1 row updated.
    --更新 114号员工的工作和工资使其与 205号员工相同
    
    UPDATE COPY_EMP
       SET DEPARTMENT_ID =
           (SELECT DEPARTMENT_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 100)
     WHERE JOB_ID = (SELECT JOB_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 200);
    --1 row updated.
    --在 UPDATE 中使用子查询,使更新基于另一个表中的数据。
    

    删除

    使用 DELETE 语句从表中删除数据。

    语法示例

    DELETE [FROM]     table
    [WHERE    condition];
    

    使用WHERE 子句指定删除的记录。

     DELETE FROM HR.departments
     WHERE  department_name = 'Finance';
    --1 row deleted.
    --如果省略WHERE子句,则表中的全部数据将被删除。
    

    在 DELETE 中使用子查询

    DELETE FROM HR.employees
    WHERE  department_id =
                           (SELECT department_id
                            FROM   HR.departments
                            WHERE  department_name LIKE '%Public%');
    --1 row deleted.
    --在 DELETE 中使用子查询,使删除基于另一个表中的数据。 
    

    高级函数处理

    NVL & NVL2

    NVL

    将空值转换成一个已知的值:可以使用的数据类型有日期、字符、数字。

    函数的一般形式:

    • NVL(commission_pct, 0)
    • NVL(hire_date, SYSDATE)
    • NVL(job_id, 'No Job Yet')

    使用示例

    SELECT last_name, salary, NVL(commission_pct, 0),
       (salary*12) + (salary*12*NVL(commission_pct, 0)) AN_SAL
    FROM hr.employees;
    --NVL(commission_pct, 0):若commission_pct是NULL,那么取0作为它的值
    

    NVL2

    SELECT last_name,  salary, commission_pct,
           NVL2(commission_pct, 'SAL+COMM', 'SAL') income
    FROM   hr.employees WHERE department_id IN (50, 80);
    --NVL2(commission_pct, 'SAL+COMM', 'SAL'):若commission_pct不是NULL,就取SAL+COMM,否则取SAL
    

    COALESCE

    COALESCE 与 NVL 相比的优点在于 COALESCE 可以同时处理交替的多个值。

    SELECT   last_name,
             COALESCE(commission_pct, salary, 10) comm
    FROM     employees
    ORDER BY commission_pct;
    -- COALESCE(commission_pct, salary, 10)是返回第一个非空的值,若commission_pct为NULL就返回salary,若salary也为NULL,就返回10
    

    在 SQL 语句中使用IF-THEN-ELSE 逻辑。

    使用两种方法:CASE 表达式DECODE 函数

    DECODE

    使用语法

    DECODE(col|expression, search1, result1 
                       [, search2, result2,...,]
                       [, default])
    

    使用示例

    SELECT last_name, job_id, salary,
           DECODE(job_id, 'IT_PROG',  1.10*salary,
                          'ST_CLERK', 1.15*salary,
                          'SA_REP',   1.20*salary,
                  salary)
           REVISED_SALARY
    FROM   employees;
    

    CASE表达式

    使用语法

    CASE expr WHEN comparison_expr1 THEN return_expr1
             [WHEN comparison_expr2 THEN return_expr2
              WHEN comparison_exprn THEN return_exprn
              ELSE else_expr]
    END
    

    使用示例

    SELECT last_name, job_id, salary,
           CASE job_id WHEN 'IT_PROG'  THEN  1.10*salary
                       WHEN 'ST_CLERK' THEN  1.15*salary
                       WHEN 'SA_REP'   THEN  1.20*salary
           ELSE      salary END     "REVISED_SALARY"
    FROM   hr.employees;
    --根据JOB_ID的值,对工资做相应的处理
    

    事务

    • 以第一个 DML 语句的执行作为开始
    • 以下面的其中之一作为结束:
      • COMMIT 或 ROLLBACK 语句
      • DDL 或 DCL 语句(自动提交)
      • 用户会话正常结束系统异常终了

    使用COMMITROLLBACK语句,我们可以:

    1. 确保数据完整性。
    2. 数据改变被提交之前预览。
    3. 将逻辑上相关的操作分组。

    视图

    • 控制数据访问
    • 简化查询
    • 数据独立性
    • 避免重复访问相同的数据

    视图创建

    语法示例

    CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view
      [(alias[, alias]...)]
     AS subquery
    [WITH CHECK OPTION [CONSTRAINT constraint]]
    [WITH READ ONLY [CONSTRAINT constraint]];
    

    创建视图

    CREATE VIEW     empvu80
     AS SELECT  employee_id, last_name, salary
        FROM    hr.employees
        WHERE   department_id = 80;
    --View created.
    

    创建视图时在子查询中给列定义别名

    CREATE VIEW     salvu50
     AS SELECT  employee_id ID_NUMBER, last_name NAME,
                salary*12 ANN_SALARY
        FROM    hr.employees
        WHERE   department_id = 50;
    --View created.
    --在选择视图中的列时应使用别名
    

    视图修改

    使用CREATE OR REPLACE VIEW 子句修改视图

    CREATE OR REPLACE VIEW empvu80
      (id_number, name, sal, department_id)
    AS SELECT  employee_id, first_name || ' ' || last_name, 
               salary, department_id
       FROM    hr.employees
       WHERE   department_id = 80;
    --View created.
    --CREATE VIEW 子句中各列的别名应和子查询中各列相对应
    

    删除视图

    删除视图只是删除视图的定义,并不会删除基表的数据

    删除语法

    DROP VIEW view;
    --删除视图view
    

    存储过程

    存储过程,Procedure,是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行。

    存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数、输出参数、返回单个或多个结果集以及返回值。

    由于存储过程在创建时即在数据库服务器上进行了编译并存储在数据库中,所以存储过程运行要比单个的SQL语句块要快。同时由于在调用时只需用提供存储过程名和必要的参数信息,所以在一定程度上也可以减少网络流量、简单网络负担。

    基本语法

    CREATE OR REPLACE PROCEDURE 存储过程名字
    (
        参数1 IN NUMBER,
        参数2 IN NUMBER
    ) IS
    变量1 INTEGER :=0;
    变量2 DATE;
    BEGIN
    [执行语句]
    END 
    

    使用示例

    创建一个表Student,并插入一百万条记录,在奇数的时候插入Tom记录,偶数的时候插入Lucy记录。使用存储过程来实现。

    Create Table student (
    s_id Number(8),
    s_name Varchar2(20),
    s_sex Char(2)
    );
    --创建表student
    
    Create Or Replace Procedure p_insert_data
    AS
    Begin
      For i In 1..1000000 Loop
      If i Mod 2 = 1 Then
        Insert into student Values(i, 'Tom', '男');
      Else
        Insert into student Values(i, 'Lucy', '女');
      End If;
    
      End Loop;
      Commit;
      dbms_output.put_line('插入数据完成!');
    End;
    --创建存储过程
    

    调用存储过程

    CALL p_insert_data();
    

    相关文章

      网友评论

      本文标题:数据库(3) | Oralce SQL 数据处理

      本文链接:https://www.haomeiwen.com/subject/uzdfrttx.html