ALTER TABLE COMPANY_EMP ADD DESCRIPTION VARCHAR2( 200 ) NULL ; -- 删除表列 ALTER TABLE COMPANY_EMP DROP COLUMN DESCRIPTION;

DROP:移除数据库对象

DROP TABLE COMPANY_EMP;

创建表副本

-- 创建表副本语句
CREATE TABLE <NEWTABLE> AS SELECT {*|COLUMN(S)} FROM <OLDTABLE> [WHERE <CONDITION>]
-- 创建emp_back 与emp 相同结构及数据
create table emp_back as SELECT * FROM emp
-- 创建emp_back 与emp 相同结构 但不包含数据
create table emp_back as SELECT * FROM emp where 1=2

5.2 创建约束

为什么要创建约束?

  • 为了保证数据的完整性而实现的一套机制,它是数据库服务器强制用户必须遵从的业务逻辑,限制用户可能输入指定范围外的值;
  • 有哪些约束?

    非空约束:NOT NULL(该值不能为空)

    唯一约束:UNIQUE(整个表相同列中是唯一的)

    检查约束:CHECK (对字段执行检查条件)

    主键约束:PRIMARY KEY(唯一约束+非空约束)

    外键约束:REFERENCES(表间关联的约束,实现数据完整性)

    CREATE TABLE TABLE_A
    VENDOR_ID NUMBER,
    INVOICE_TOTAL NUMBER(9,2) CHECK (INVOICE_TOTAL>0 AND 
    INVOICE_TOTAL<=5000),                           -- 检查约束
    VENDOR_NAME VARCHAR2(50) NOT NULL,              -- 非空约束
    CONSTRAINT VENDORS_PK PRIMARY KEY (VENDOR_ID)   -- 主键
    CONSTRAINT VENDOR_NAME_UQ UNIQUE (VENDOR_NAME)  -- 唯一约束
    

    如何查看约束?

    -- constraints 
    SELECT * FROM user_constraints t where t.constraint_name = 'PRIMART_ENPNO';
    

    5.3 修改表

    ALTER TABLE 修改表列的4件事

  • 向表中添加的列
  • 修改已经存在的列的类型或数据范围
  • 删除已经存在的列
  • 重命名表列
  • SELECT * FROM emp; 
    -- 增加列
    alter table emp add yang varchar2(20);
    -- 删除列
    alter table emp drop column yang;
    -- 重命名列名
    alter table emp rename column yang to yang_new;
    -- 修改列类型和检查约束(慎用)
    alter table emp modify yang_new varchar(40) check(length(yang_new)<30);
    

    ALTER TABLE 修改约束的3件事

  • 向表中添加一个新的约束
  • 移除表中现有的约束
  • 启用或禁用约束
  • -- 删除约束 DROP
    ALTER TABLE EMP DROP CONSTRAINT PRIMART_ENPNO;
    -- 添加约束
    ALTER TABLE EMP ADD CONSTRAINT UQ_CONSTR UNIQUE (ENAME);
    ALTER TABLE EMP ADD CONSTRAINT PRIMART_ENPNO PRIMARY KEY(EMPNO);
    

    移除数据表

    -- 删除表,同时删除数据、表结构及约束
    DROP TABLE EMP;
    -- 当表有外键约束时,应先移除外键表,在移除该表
    

    5.4 索引

    索引是建立在数据库中的一列或多列用来加速访问表中数据的辅助对象;

  • 加快检索数据的速度
  • 保证数据唯一性
  • 加快表与表之间的连接
  • 减少查询分组和排序时间
  • 5.5 视图

    6. 查询数据表

    查询相关关键字:

    DISTINCT :该列去重

    AS : 改列别名 (当使用字符串为别名时,必须使用双引号标注字符串)

    NULL : (IS NULL 或 IS NOT NULL)

    || : 字符串连接符

    范围操作符

    BETWEEN-AND : 比较的值是否在两个值之间

    IN :比较的值是否在任意的值列表中间

    LIKE:通配符类匹配一个字符模板

  • %:表示0个或多个字符
  • _:表示一个字符
  • -- 可用于类似的分页
    SELECT * FROM (
    SELECT t.*,rownum rn FROM emp t) a where a.rn>1 and a.rn<4
    

    ROWID伪列:记录物理位置的一个ID,常用于 更新数据、删除完全重复的两条记录

    -- 删除重复行
    DELETE FROM EMP_BACK WHERE ROWID NOT IN (SELECT MIN(ROWID) FROM EMP_BACK GROUP BY EMPNO)
    -- 更新
    SELECT T.*,ROWID FROM EMP;
    

    多表连接查询

    -- 内连接
    SELECT * FROM test6 t1,test_61 t2 where t1.id = t2.id;
    -- 左连接
    SELECT * FROM test6 t1,test_61 t2 where t1.id = t2.id(+);
    SELECT * FROM TEST6 T1 LEFT JOIN TEST_61 T2 ON T1.ID = T2.ID; 
    -- 右连接
    SELECT * FROM test6 t1,test_61 t2 where t1.id(+) = t2.id;
    SELECT * FROM TEST6 T1 RIGHT JOIN TEST_61 T2 ON T1.ID = T2.ID;
    -- 全连接
    SELECT * FROM TEST6 T1 FULL JOIN TEST_61 T2 ON T1.ID = T2.ID;
    

    相关子查询

  • 内查询依赖于外部查询的数据,外查询执行一次,内查询就执行一次
  • 非相关子查询

    内查询只执行一次,并将执行结果返回给外查询

    单行单列:

  • 比较运算符:IN、>、<、=、!=、>=、<=
  • SELECT *
      FROM test6
     where id = (SELECT t.id FROM test_61 t where t.e_name = 'yang');
    
  • ANY、ALL
  •  -- <ANY  小于最大值
     -- >ANY  大于最小值
     -- =ANY  等同于 IN
     -- <ALL  小于最小值
     -- >ALL  大于最大值
     SELECT *
       FROM test6
      where id  >all
      (SELECT t.id FROM test_61 t where t.e_name in ('de','yang'));
    
    -- 语句中的列顺序可以不按表列顺序,单VALUES 里面的顺序必须跟语句中的列顺序一致
    INSERT INTO TEST6(ENAME,ID,NAME,AGE)VALUES('laowang',6,'老王',78);
    -- 可以这么用,但它并不方便
    INSERT INTO TEST6_BACK SELECT 11,'老八',19,0,'laoba',sysdate FROM DUAL;
    
    -- 跟插入单行一样,只是插入多行的结果集多一点而已,通常更新更新整表,部也是如此
    INSERT INTO TEST6_BACK SELECT * FROM TEST6 T WHERE T.ID > 4;
    
    --------------插入多表语法---------------------
    -- 参数FIRST 当WHEN条件成功将执行该THEN且跳过后面WHEN字句
    -- 参数ALL 执行每一个WHEN,不管前面是否成功,都将执行后面的WHEN
    -- 参数ELSE 当条件都不满足时,执行ELSE中的插入子句
    -- SUBQUERY 要进行多表插入的子查询
    INSERT {FIRST|ALL} 
       [WHEN CONDITION THEN] INTO TABLE [VALUES(...)]
       [WHEN CONDITION THEN] INTO TABLE [VALUES(...)]
       ELSE INTO TABLE [VALUES(...)]
       SUBQUERY;
    ------------------实例------------------------
    INSERT FIRST          -- 参数FIRST 当WHEN条件成功将执行该THEN且跳过后面WHEN字句
       WHEN MOD(ID,2)=0   -- 偶数将插入TEST_01表
           INTO TEST_01
       WHEN MOD(ID,2)<>0  -- 奇数将插入TEST_02表
           INTO TEST_02
         INTO TEST_03     -- 前面都不满足的情况下将插入TEST_03表, 该例此子句无意义
    SELECT * FROM TEST6;
    
    -- 两种方式
    UPDATE TEST6 SET AGE=17 WHERE ID = 2;  -- 先确定更新表、再过滤列
    update (SELECT * FROM TEST6 WHERE ID = 2) set age =77; -- 通过子查询先过滤列,再将子查询当作表更新  
    

    MERGE合并表行

    对比两个表,针对条件判断执行两种选择

    -- 该例 为存在该ID 则更新其他列,不存在该ID 则插入到目标表
    MERGE INTO TEST_01 C         -- 目标表
    USING TEST6 E                -- 原表
    ON (C.ID = E.ID)             -- 条件
    WHEN MATCHED THEN            -- 满足条件将执行下面代码
      UPDATE
      SET C.NAME = E.NAME,C.AGE=E.AGE,C.SEX=E.SEX,
      C.ENAME=E.ENAME,C.ADDTIME=E.ADDTIME
    WHEN NOT MATCHED THEN        -- 不满足条件将执行下面代码
      INSERT VALUES(
      E.ID,E.NAME,E.AGE,E.SEX,
      E.ENAME,E.ADDTIME)
    

    如果一次性清除表中数据且不需要撤销,使用TRUNCATE语句

    -- DELETE FROM RESULT_COLUMN(结果集所有行)   将删除结果集所有行
    -- 删除单行记录 DELETE FROM 
    delete from test6 where id = 8;  -- 先确定删除表,再确定行
    delete from (SELECT * FROM test6 t where t.id =8); -- 通过子查询先过滤行,再将子查询当作删除行
    

    删除多行记录

    -- 通过相关子查询删除多行记录
    DELETE FROM TEST6_BACK X WHERE EXISTS(SELECT 1 FROM TEST6 T2 WHERE T2.ID = X.ID )
    

    TRUNCATE清除表数据

  • TRUNCATE数据DDL数据定义语言,跟CREATE TABEL等语句一样,不具有撤销功能
  • 速度比DELETE效率高
  • 不会激活表的删除触发器
  • 有主外键关系的主表,使用TRUNCATE前禁用该约束
  • 因属于DDL语言,因此不能被PL/SQL语句块调用,必须使用动态语句调用方式 : EXECUTE IMMEDIATE V_SQL;
  • TRUNCATE TABLE TEST6_BACK;
    
  • 提交COMMIT:当执行DML语言时,隐式事务激活,被DML(insert、update、delete)操作的数据被放在数据段中,此时必须显示提交事务COMMIT,物理数据库才会更改
  • 回滚ROLLBACK:当执行DML语言时,旧数据保存到回退表空间(UNDO TABLESPACE)中,执行ROLLBACK后,Oracle 会将回退表空间中的数据写到数据段中
  • 主要用途是创建一个主键的值,它独立于表存储和生成

    -- 序列创建
    CREATE SEQUENCE SEQUENCE_NAME  
    [INCREMENT BY N]              -- 序列步长,默认为1
    [START WITH N]                -- 序列初始值, 默认为1
    [{MAXVALUE N | NOMAXVALUE}]   -- 最大值, 默认没有最大值定义
    [{MINVALUE N | NOMINVALUE}]   -- 最小值, 默认最小值为1
    [{CYCLE | NOCYCLE}]           -- 是否循环
    [{CACHE N | NOCACHE}];        -- 定义缓存数,默认为20
    
  • NEXTVAL : 返回下一个可用序列值(SEQUENCE_NAME.NEXTVAL)
  • CURRVAL:获得当前的序列值(SEQUENCE_NAME.CURRVAL)
  • 8. 记录与集合

    DECLARE TYPE INX_TABLE IS TABLE OF VARCHAR2(10)    -- 定义INX_TABLE 为索引表名 INDEX BY pls_integer;     -- pls_integer 为使用整数为索引 V_Y INX_TABLE;            -- 定义索引表变量 BEGIN  FOR I IN 1.. 10 LOOP   V_Y(I):='HHD00'||I;    END LOOP;  FOR Y IN 1.. 10 LOOP   DBMS_OUTPUT.put_line(V_Y(Y));    END LOOP;  END; -- 实例,字符串索引 DECLARE A1 VARCHAR2(10); A2 VARCHAR2(10); TYPE INX_TABLE IS TABLE OF VARCHAR2(20) INDEX BY varchar2(20); V_Y INX_TABLE; BEGIN  FOR I IN 1.. 10 LOOP   A1 := '单据00'||I;   V_Y(A1) :='DH00'||I;    --DBMS_OUTPUT.put_line(V_Y(A1));    END LOOP;    FOR Y IN 1.. 10 LOOP   A2 := '单据00'||Y;   DBMS_OUTPUT.put_line(V_Y(A2));    END LOOP;  END;

    \

    分类:
    后端
    标签: