zoukankan      html  css  js  c++  java
  • oracle之DML和DDL语句的其他用法

    DML和DDL语句的其他用法

    17.1 DML语句-MERGE

    作用:把数据从一个表复制到另一个表,插入新数据或替换掉老数据。

    Oracle 10g中MERGE有如下一些改进:

    1、UPDATE或INSERT子句是可选的
    2、UPDATE和INSERT子句可以加WHERE子句
    3、ON条件中使用常量过滤谓词来insert所有的行到目标表中,不需要连接源表和目标表
    4、UPDATE子句后面可以跟DELETE子句来去除一些不需要的行

    首先创建示例表:

    create table PRODUCTS
        (
        PRODUCT_ID INTEGER,
        PRODUCT_NAME VARCHAR2(30),
        CATEGORY VARCHAR2(30)
        );

    insert into PRODUCTS values (1501, 'VIVITAR 35MM', 'ELECTRNCS');
    insert into PRODUCTS values (1502, 'OLYMPUS IS50', 'ELECTRNCS');
    insert into PRODUCTS values (1600, 'PLAY GYM', 'TOYS');
    insert into PRODUCTS values (1601, 'LAMAZE', 'TOYS');
    insert into PRODUCTS values (1666, 'HARRY POTTER', 'DVD');
    commit;


    create table NEWPRODUCTS
        (
        PRODUCT_ID INTEGER,
        PRODUCT_NAME VARCHAR2(30),
        CATEGORY VARCHAR2(30)
        );

    insert into NEWPRODUCTS values (1502, 'OLYMPUS CAMERA', 'ELECTRNCS');
    insert into NEWPRODUCTS values (1601, 'LAMAZE', 'TOYS');
    insert into NEWPRODUCTS values (1666, 'HARRY POTTER', 'TOYS');
    insert into NEWPRODUCTS values (1700, 'WAIT INTERFACE', 'BOOKS');
    commit;

    SQL>select * from products;

    PRODUCT_ID PRODUCT_NAME                   CATEGORY
    ---------- ------------------------------ ------------------------------
          1501 VIVITAR 35MM                       ELECTRNCS
          1502 OLYMPUS IS50                       ELECTRNCS
          1600 PLAY GYM                           TOYS
          1601 LAMAZE                             TOYS
          1666 HARRY POTTER                       DVD

    SQL> select * from newproducts;

    PRODUCT_ID PRODUCT_NAME                   CATEGORY
    ---------- ------------------------------ ------------------------------
          1502 OLYMPUS CAMERA                 ELECTRNCS
          1601 LAMAZE                             TOYS
          1666 HARRY POTTER                       TOYS
          1700 WAIT INTERFACE                     BOOKS

    下面例子我们从表NEWPRODUCTS中合并行到表PRODUCTS中, 但删除category为ELECTRNCS的行.

    SQL>MERGE INTO products p
    USING newproducts np
    ON (p.product_id = np.product_id)
    WHEN MATCHED THEN
    UPDATE
    SET p.product_name = np.product_name,p.category = np.category
    DELETE WHERE (p.category = 'ELECTRNCS')
    WHEN NOT MATCHED THEN
    INSERT
    VALUES (np.product_id, np.product_name, np.category);
     
    4 rows merged.

    SQL>select * from products;

    PRODUCT_ID PRODUCT_NAME                   CATEGORY
    ---------- ------------------------------ ------------------------------
          1501 VIVITAR 35MM                       ELECTRNCS
          1600 PLAY GYM                           TOYS
          1601 LAMAZE                             TOYS
          1666 HARRY POTTER                       TOYS
          1700 WAIT INTERFACE                     BOOKS

    为什么1502不在了,但1501还在? 因为1502是matched,先被update,然后被delete, 而1501是not matched.

    注意几点:
    1)例子里有update,delete和insert。它们是否操作是取决于on子句的,首先两个表如果符合on条件就是匹配,不符合就是不匹配。
    2)匹配了就更新,不匹配则插入。这是最初9i的原则,10g后加入了delete语句,这个语句必须在匹配条件下出现。它是一种补充。
    3)你必须对操作的表有对象权限。
    4)ON子句里的字段不能被update子句更新(考点)

    17.2 with语句

    我们可以使用一个关键字WITH, 给一个子查询块(subquery block)起一个别名. 然后在后面的查询中引用这个子查询块的别名。

    好处:
    1、使用with语句,可以避免在select语句中重复书写相同的语句块。
    2、with语句将该子句中的语句块执行一次并存储到用户的临时表空间中。
    3、使用with语句可以避免重复解析,提高查询效率。

    举例:这个with语句完成三个动作

    建立一个dept_costs,保存每个部门的工资总和,
    建立一个avg_cost,根据dept_costs求出所有部门总工资的平均值,
    最后显示出部门总工资值小于部门总工资平均值的那些部门的信息(dname)。

    WITH
    dept_costs AS (
    SELECT d.dname, SUM(e.sal) AS dept_total
    FROM emp e, dept d
    WHERE e.deptno = d.deptno
    GROUP BY d.dname ),   

    avg_cost AS (
    SELECT SUM(dept_total)/COUNT(*) AS dept_avg FROM dept_costs )
    SELECT * FROM dept_costs
    WHERE dept_total <
    (SELECT dept_avg FROM avg_cost)   
    ORDER BY dname
    /


    DNAME          DEPT_TOTAL
    -------------- ----------
    ACCOUNTING         8750
    SALES                    9400


    可以分三个部分来看:
    第一AS建立dept_costs,保存每个部门的工资总和。
    第二个AS建立avg_cost,根据第一个AS dept_costs求出所有部门总工资的平均值(两个with子程序用逗号分开,第二个使用了第一个别名)。
    最后是查询主体,SELECT * FROM... 调用了前两个with下的别名(子查询),显示部门总工资值小于部门总工资平均值的那些部门的信息。

    考点:
    1)with语句中只能有select子句,没有DML子句(注意和merge的区别)。
    2)一般将主查询放在最后描述,因为查询主体中要引用的with别名需要在之前定义过。


    17.3 DDL操作及名称空间

    17.3.1 模式与对象名称空间的关系

    模式(Schema)是一种逻辑结构,它对应于用户,每建一个用户就有一套模式与之对应。
    我们通常说对象的唯一标识符是前缀为模式名加上对象名称,如scott.emp。
    同一模式下的同类对象是不可以重名的。比如在scott模式里,表emp是唯一的,但在不同模式下可以重名。

    名称空间定义了一组对象类型,同一个名称空间里的不同对象不能同名,而不同的名称空间中的不同对象可以共享相同的名称。

    1)表,视图,序列,同义词是不同类型的对象,但它们属于同一名称空间, 因此在同一模式下也是不可以重名的,比如scott下不可以让一个表名和一个视图名同名。
    2)索引、约束有自己的名称空间,所以在scott模式下,可以有表A,索引A和约束A共存。

    考点:在同一个模式中,表、视图和同义词不能同名。

    17.3.2 使用子查询创建表

    关于CTAS结构:create table as subquery;

    如:create table 表2 as select * from 表1;是最简洁的复制表的命令,但是要注意几点:

    1)表1的索引不会被复制给表2
    2)表1中的约束只有not null约束能够带到表2里来(考点),
    3)表1中如果有default也不会被复制到表2。
    4)由于需要建立表2,则表2列的命名必须符合规范。通常对表2或表1有选择的指定别名。(考点)
    5)表2可以有default选项。(考点)

    17.3.3 改变表结构的DDL操作

    1)在数据库打开的情况下,可以使用DDL语句更改表列,如增加(add),删除(drop),修改(midify),更名(rename)等。

    drop和rename语法上要加column关键字。

    原理:清除掉字典信息(撤消存储空间),不可恢复。

    2)当想要add一列,并约束该列为not null时,如果该表已经有数据了,加的列本身是null,则与not null约束矛盾,报错 。

    SQL> select * from a;

            ID NAME        
    ---------- ----------
             1 a
             2 b

    SQL> alter table a add C number(5) not null;
    alter table a add C number(5) not null
                *
    第 1 行出现错误:
    ORA-01758: 要添加必需的 (NOT NULL) 列, 则表必须为空

    SQL> alter table a add C number(5) default 0 not null;

    修改成功了,可以看到C列全是0,这样才能使C列的约束为not null (考点)

    3)要删除某一个表格上的某个字段,但是由于这个表格拥有非常大量的资料,如果你在尖峰时间直接执行 ALTER TABLE ABC DROP (COLUMN);可能会收到 ORA-01562 - failed to extend rollback segment number string,这是因为在这个删除字段的过程中你可能会消耗光整个RBS。

    Oracle推荐:使用 SET UNUSED 选项标记一列(或多列),使该列不可用。
    然后,当业务量下降后再使用DROP UNUSED column 选项删除被被标记为不可用的列。SET UNUSED COLUMNS用于drop多列时效率更高,

    SET UNUSED COLUMNS 方法系统开销比较小,速度较快,但效果等同于直接drop column。就是说这两种方法都不可逆,无法再还原该字段及其内容了。

    语法:
    ALTER TABLE table SET UNUSED  [column] (COLlist多个)
    ALTER TABLE table DROP UNUSED [COLUMN];

    考点:
    1)如果set unused某列,该列上有索引,约束,并定义了视图,引用过序列,结果如何,索引和约束自动删除,序列无关,视图保留定义。
    2)无法删除属于 SYS 的表中的列,会报ORA-12988错误,哪怕你是sys用户都不可以。

    实验:scott下
    create table a (id int, name char(10));    
    create index id_idx on a(id);
    alter table a add constraint unq_id unique(id);    
    create sequence a_id start with 1 increment by 1;
    create view v as select id from a;            
    insert into a values(a_id.nextval,'tim');
    insert into a values(a_id.nextval,'ran');          
    commit;

    SQL> select * from a;

            ID NAME
    ---------- ----------
             1 tim
             2 ran

    SQL> select index_name from user_indexes where table_name='A';        --查看有关索引

    INDEX_NAME
    ------------------------------
    ID_IDX

    SQL> select constraint_name from user_constraints where table_name='A';     --查看有关约束

    CONSTRAINT_NAME
    ------------------------------
    UNQ_ID

    SQL> select object_name from user_objects where object_type='SEQUENCE';     --查看有关序列

    OBJECT_NAME
    -----------------------------------------
    A_ID

    SQL> select text from user_views where view_name='V';            --查看有关视图    

    TEXT
    --------------------------------------------------------------------------------
    select id from a

    SQL> alter table a drop column id;

    重复查看有关信息,索引和约束随该列数据虽然被删除,但序列和视图的定义还在。

  • 相关阅读:
    Docker概念学习系列之详谈Docker 的核心组件与概念(5)
    全网最详细的如何在谷歌浏览器里正确下载并安装Postman【一款功能强大的网页调试与发送网页HTTP请求的Chrome插件】(图文详解)
    全网最详细的一款满足多台电脑共用一个鼠标和键盘的工具Synergy(图文详解)
    [转]华为开发者联盟开放的服务
    [转]英语发音规则---E字母常见的发音组合有哪些
    [转]【信息系统项目管理师】重点整理:高项知识地图
    [转]【信息系统项目管理师】高项案例分析攻略
    [转]【信息系统项目管理师】案例分析记忆题
    [转]850 Basic English words
    [转]信息系统项目管理师计算题汇总
  • 原文地址:https://www.cnblogs.com/jinxf/p/9166659.html
Copyright © 2011-2022 走看看