zoukankan      html  css  js  c++  java
  • Oracle丶

    完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例。

    • 数据库是一系列物理文件的集合(数据文件,控制文件,联机日志,参数文件等);
    • Oracle数据库实例则是一组Oracle后台进程/线程以及在服务器分配的共享内存区。

    在启动Oracle数据库服务器时,实际上是在服务器的内存中创建一个Oracle实例(即在服务器内存中分配共享内存并创建相关的后台内存),然后由这个Oracle数据库实例来访问和控制磁盘中的数据文件。Oracle有一个很大的内存快,成为全局区(SGA)。

    数据库

    数据库是数据集合。Oracle是一种数据库管理系统,是一种关系型的数据库管理系统。
    通常情况了我们称的“数据库”,并不仅指物理的数据集合,他包含物理数据、数据库管理系统。也即物理数据、内存、操作系统进程的组合体。

    select name from v$database;
    

    数据库实例

    实例是访问Oracle数据库所需的一部分计算机内存和辅助处理后台进程,是由进程和这些进程所使用的内存(SGA)所构成一个集合。其实就是用来访问和使用数据库的一块进程,它只存在于内存中。我们访问Oracle就是访问一个实例

    • 实例名指的是用于响应某个数据库操作的数据库管理系统的名称。她同时也叫SID。实例名是由参数instance_name决定的。
    • 一个数据库可以有多个实例,在作数据库服务集群的时候可以用到
    select instance_name from v$instance;
    -- jdbc:oracle:thin:@localhost:1521:orcl(orcl就为数据库实例名)
    

    表空间

    img

    Oracle数据库是通过表空间来存储物理表的,一个数据库实例可以有N个表空间,一个表空间下可以有N张表。

    • 有了数据库,就可以创建表空间。
    • 表空间(tablespace)是数据库的逻辑划分,每个数据库至少有一个表空间(称作SYSTEM表空间)。
    • 为了便于管理和提高运行效率,可以使用一些附加表空间来划分用户和应用程序。(例如:USER表空间供一般用户使用,RBS表空间供回滚段使用。)
    • 一个表空间只能属于一个数据库。

    img

    -- 创建表空间语法
    create tablespace db_test  -- 表空间名称
    datafile 'D:oracleproduct10.2.0userdatadb_test.dbf'  -- 表空间数据文件路径  
    size 50m  -- 表空间初始大小
    autoextend on;
    -- 查看已经创建好的表空间:
    select default_tablespace, temporary_tablespace, d.username  
    from dba_users d
    

    用户

    Oracle数据库建好后,要想在数据库里建表,必须先为数据库建立用户,并为用户指定表空间。

    -- 创建新用户
    CREATE USER utest  -- 用户名  
    IDENTIFIED BY utestpwd  -- 密码 
    DEFAULT TABLESPACE db_test   -- 表空间(默认USERS) 
    TEMPORARY TABLESPACE temp;  -- 临时表空间(默认TEMP)
    -- 分配权限
    GRANT CONNECT TO utest;  
    GRANT RESOURCE TO utest;  
    GRANT dba TO utest;   -- dba为最高级权限,可以创建数据库,表等。
    -- 查看数据库用户
    select  * from dba_users;
    

    有些时候查询表数据需要在表前加上用户名(表空间对应用户的原因)

    SQL查询01

    select userenv('language') from dual;--AMERICAN_AMERICA.ZHS16GBK 环境变量(列名中文别名显示)
    select * from V$NLS_PARAMETERS--AMERICAN
    -- 解锁 scott 用户并重新设置密码
    alter user scott account unlock;
    alter user scott identified by tiger;
    -- =====基本查询
    --1.查询出所有emp中的信息,并用中文进行字段重命名   就别名用双引号
    select empno as "员工编号",ename "员工姓名",job 职位,mgr "领导编号",hiredate "入职日期",sal "工资",comm "奖金",deptno "部门编号" from emp;
    --2.查询emp表中员工的job信息,并去除重复信息
    select distinct(job) from emp;
    --3.查询emp表中员工的全年的工资总和(sal总和)
    select ename,12*sal from emp;
    --4.查询emp表中员工的全年收入总和(sal+comm的总和) nvl表示判断空值,为空用0替代
    select ename,12*sal+nvl(comm,0) from emp;
    --5.查询emp表中员工编号,姓名
    --输出格式如下:编号:xxx,姓名:xxx
    ----Concat拼接方式
    select concat(concat('编号:',empno),concat(',姓名:',ename)) from emp;
    ----Oracle的||方式  相当于我们熟悉的加号
    select '编号'||empno||',姓名:'||ename from emp;
    --=============================================条件查询
    --1.查询工资大于1500的员工
    select * from emp where sal >= 1500;
    --2.查询工资大于1500并且有奖金的雇员
    select * from emp where sal >= 1500 and comm  is not null;
    --3.查询工资大于1500或者有奖金的雇员
    select * from emp where sal >= 1500 or comm  is not null;
    --4.查询工资大于1500并且没有奖金的雇员
    select * from emp where sal >= 1500 and comm  is null;
    --5.查询员工姓名为smith的员工
    select * from emp where ename = 'SMITH';
    --=============================================范围查询
    --1.查询工资大于1500但小于3000的全部雇员
    ---->=,<=方式
    select * from emp where sal >= 1500 and sal <= 3000;
    ----between and方式
    select * from emp where sal between 1500 and 3000;
    --2.查询1981-1-1到1981-12-31号入职的雇员(between and)
    select * from emp where hiredate between to_date('1981-1-1','yyyy-MM-dd') and to_date('1981-12-31','yyyy-MM-dd')
    --3.查询员工编号是7369,7654,7566的员工
    ----OR方式
    select * from emp where empno = 7369 or empno = 7654 or empno = 7566
    ----IN方式
    select * from emp where empno in(7369,7654,7566)
    --4.查询雇员姓名是'SMITH','ALLEN','WARD'的雇员信息
    ----IN方式
    select * from emp where ename in('SMITH','ALLEN','WARD')
    --=============================================模糊查询like
    --1.查询所有雇员姓名中第二个字符有‘M’的雇员
    select * from emp where ename like '_M%'
    --2.查询名字中带有‘M’的雇员
    select * from emp where ename like '%M%'
    --3.查询雇员编号不是7369的雇员信息
    ----<>方式
    select * from emp where empno <> 7369;
    ----!=方式
    select * from emp where empno != 7369;
    --=============================================排序 order by
    --1.查询雇员的工资进行降序排序
    select ename,sal from emp order by sal desc;
    --2.查询雇员的奖金并做降序排序(关于nulls first/nulls last)
    select ename,comm from emp order by comm desc nulls last;
    --3.查询雇员的工资做降序排列并且其中奖金部分是升序排序
    select ename,sal,comm from emp order by sal desc,comm asc;
    --===========单行函数
    /*
    伪表,虚表:dual  没有任何的实际意义,只是为了补全Oracle查询语法
    */
    --字符函数
    --1.将'smith'转换成大写--关键字:upper
    select upper('smith') from dual;
    --2.将'SMITH'转换成小写--关键字:lower
    select lower(ename) from emp;
    --3.将'smith'首字母大写--关键字:initcap
    select initcap(ename) from emp;
    --4.将'helloworld'截取字符串成'hello'--关键字substr
    select substr('helloworld',0,5) from dual;
    --5.获取'hello'的字符串长度--关键字length
    select length('hello') from dual;
    --6.将'hello'中的l用x进行替换--关键字replace
    select replace('hello','l','x') from dual;
    --数值函数
    --1.将15.66进行四舍五入(从-2到2)--关键字round
    select round(15.66,-2) from dual;  --0
    select round(15.66,-1) from dual; --20
    select round(15.66,0) from dual; --16
    select round(15.66,1) from dual; --15.7
    select round(15.66,2) from dual; --15.66
    --2.将15.66进行截断(从-2到2)--关键字trunc
    select trunc(15.66,-2) from dual;  --0
    select trunc(15.66,-1) from dual; --10
    select trunc(15.66,0) from dual; --15
    select trunc(15.66,1) from dual; --15.6
    select trunc(15.66,2) from dual; --15.66
    --3.对15/3进行求余数--关键字mod
    select mod(15,3) from dual;
    --日期函数
    --1.查询系统时间--关键字sysdate
    select sysdate from dual;
    --2.查询雇员进入公司的周数
    select ename,(sysdate-hiredate)/7 from emp
    --3.查询雇员进入公司的月数--关键字months_between
    select ename,months_between(sysdate,hiredate) from emp;
    --4.求出三个月后的日期--关键字add_months
    select ename,hiredate,add_months(hiredate,3) from emp;
    --转换函数
    --1.将系统日期显示为yyyy-mm-dd hh:mi:ss(去掉补零和24小时显示时间)--关键字to_char
    select to_char(sysdate,'yyyyfm-mm-dd hh24:mi:ss') from dual;
    ----显示成年月日
    select to_char(sysdate,'yyyy')||'年'||to_char(sysdate,'MM')||'月'||to_char(sysdate,'dd')||'日' from dual;
    --2.将字符串'1981-1-1'转换成日期类型--关键字to_date
    select to_date('1981-1-1','yyyy-MM-dd') from dual;
    select to_number('99') from dual;
    select to_char(99) from dual;
    --通用函数
    --1.空值的处理函数
    select nvl(comm,0) from emp;
    --2.nvl2(判断值,空返回值,非空返回值) 
    select nvl2('xxxxxx','1','2') from dual;
    --条件表达式
    --1.查询员工的job内容并转成中文显示
    ----decode方式
    select ename,decode(job,'CLERK','柜员','SALESMAN','销售','MANAGER','管理','其他') from emp;
    ----case when then end方式
    select ename, case job when 'CLERK'  then  '柜员' 
                           when 'SALESMAN'  then  '销售'
                           when 'MANAGER'  then  '管理'
         else
           '其他'
           end from emp;
    --===========多行函数
    --1.查询所有员工记录数--关键字count
    select count(*) from emp;
    --2.查询佣金的总数--(如何查询某个字段的总数量)
    select sum(comm) from emp;
    --3.查询最低工资--关键字min
    select min(sal) from emp;
    --4.查询最高工资--关键字max
    select max(sal) from emp;
    --5.查询平均工资--关键字avg
    select avg(sal) from emp;
    --6.查询20号部门的员工工资总和
    select sum(sal) from emp where deptno = 20;
    --======================================分组函数
    --1.查询部门编号及人数--分组查询关键字group by
    select deptno,count(*) from emp group by deptno;
    --2.查询每个部门编号及平均工资
    select deptno,avg(sal) from emp group by deptno;
    --3.查询部门名称,部门编号,平均工资
    select dname,emp.deptno,avg(sal) from dept,emp where dept.deptno = emp.deptno group by emp.deptno,dname
    --4.查询出部门人数大于5人的部门
    select deptno,count(*) from emp group by deptno having count(*) > 5
    --5.查询部门编号,部门名称,平均工资且平均工资大于2000
    select emp.deptno,dname,avg(sal) from emp,dept where emp.deptno = dept.deptno
     group by emp.deptno,dname having avg(sal) > 2000;
    

    SQL查询02

    --======================================多表关联查询
    --查询员工编号,员工姓名,员工部门编号,员工部门名称,员工部门地址,中文显示员工工资等级,及领导编号,领导姓名,领导部门编号,领导部门名称,中文显示领导工资等级
    select * from salgrade;
    select * from emp;
    select * from dept;
    
    select e1.empno,e1.ename,e1.deptno,d1.dname,d1.loc,decode(s1.grade,1,'一级',2,'二级',3,'三级',4,'四级',5,'五级') "salLevel",e1.mgr,e2.ename,e2.deptno,d2.dname,decode(s2.grade,1,'一级',2,'二级',3,'三级',4,'四级',5,'五级') "salLevel"
    from emp e1,dept d1,salgrade s1,emp e2,dept d2,salgrade s2 
     where e1.deptno = d1.deptno and e1.sal between s1.losal and s1.hisal
    and e1.mgr = e2.empno and e2.deptno = d2.deptno and e2.sal between s2.losal and s2.hisal 
    --1.查询员工编号,员工姓名,领导编号,领导姓名
    --2.查询员工编号,员工姓名,员工部门编号,员工部门名称,员工部门地址,领导编号,领导姓名,领导部门编号,领导部门名称
    --3.查询员工编号,员工姓名,员工部门编号,员工部门名称,员工部门地址,员工工资等级,领导编号,领导姓名,领导部门编号,领导部门名称,领导工资等级
    --4.查询员工编号,员工姓名,员工部门编号,员工部门名称,员工部门地址,中文显示员工工资等级,领导编号,领导姓名,领导部门编号,领导部门名称,中文显示领导工资等级
    
    select e1.empno,e1.ename,e1.deptno,d1.dname,d1.loc,decode(s1.grade,1,'一级',2,'二级',3,'三级',4,'四级',5,'五级'),e2.empno,e2.ename,e2.deptno,d2.dname,d2.loc,decode(s2.grade,1,'一级',2,'二级',3,'三级',4,'四级',5,'五级') from emp e1,emp e2,dept d1,dept d2,salgrade s1,salgrade s2 where 
    e1.mgr = e2.empno and e1.sal between s1.losal and s1.hisal
    and e1.deptno = d1.deptno and e2.sal between s2.losal and s2.hisal
    and e2.deptno = d2.deptno
    
    --======================================外连接
    --1.查询员工编号,姓名,领导编号,领导姓名,包括没领导的
    ----left join on方式
    select e1.empno,e1.ename,e2.empno,e2.ename  from emp e1 left join emp e2 on e1.mgr = e2.empno
    
    ----Orcl的(+)方式
    select e1.empno,e1.ename,e2.empno,e2.ename from emp e1,emp e2 where e1.mgr = e2.empno(+)
    
    --2.查询出所有部门信息(包括没员工的部门)及部门下的员工信息
    select * from emp,dept where emp.deptno(+) = dept.deptno;
    
    --===========子查询
    --1.查询比雇员7654工资高,同时从事和7788的工作一样的员工
    select * from emp where sal > (select sal from emp where empno = 7654)
    and job = (select job from emp where empno = 7788);
    
    --2.查询每个部门最低工资及最低工资的部门名称和雇员名称
    select emp.empno,emp.ename,e1.minsal,e1.deptno from (select min(sal) minsal,deptno from emp group by deptno) e1,emp,dept 
    where e1.deptno = dept.deptno and emp.deptno = e1.deptno and e1.minsal = emp.sal;
    
    select * from dept;
    select * from emp;
    --===========课堂练习
    --1.找到员工表中工资最高的前三名
    select rownum,empno,ename,sal from emp  order by sal desc;
    select rownum,e.* from (select emp.* from emp order by sal desc)e where rownum <=3
    
    --2.找到员工表中薪水大于本部门平均工资的所有员工
    select emp.empno,emp.ename,e1.avgsal,e1.deptno,emp.sal from (select avg(sal) avgsal,deptno from emp group by deptno) e1,emp 
    where e1.deptno = emp.deptno and e1.avgsal < emp.sal
    
    select avg(sal),deptno from emp group by deptno
    select * from emp;
    --3.统计每年入职的员工个数
    select count(*),to_char(hiredate,'yyyy') from emp group by to_char(hiredate,'yyyy');
    
    select sum(hcount) "Total",sum(decode(hdate,'1980',hcount)) "1980",min(decode(hdate,'1981',hcount)) "1981",max(decode(hdate,'1982',hcount)) "1982",avg(decode(hdate,'1987',hcount)) "1987" from (select count(*) hcount,to_char(hiredate,'yyyy') hdate from emp group by to_char(hiredate,'yyyy')) e;
    --===========分页查询
    --1.查询员工表,将员工工资进行降序查询,并进行分页取出第一页,一页三条记录
    select * from (select rownum r,e.* from (select * from emp order by sal desc)e) e1 
    where r > 0 and r <= 3
    /*
    分页公式
    pageNo = 1
    pageSize = 3
    select * from (select rownum r,e.* from (select * from 表名 order by 列名 desc)e) e1 
    where r > (pageNo - 1)*pageSize and r <= pageNo*pageSize
    */
    
    --===========集合运算(了解)
    --1.查询工资大于1200并且job是SALESMAN(intersect)
    select * from emp where sal > 1200
    intersect
    select * from emp where job = 'SALESMAN'
    
    --2.查询工资大于1200或者job是SALESMAN(union)
    select * from emp where sal > 1200 
    union
    select * from emp where job = 'SALESMAN' 
    
    --3.求工资大约1200和job是SALESMAN的差集(minus)
    select * from emp where sal > 1200 
    minus
    select * from emp where job = 'SALESMAN'
    
    --==========================exists / not exists
    /*
    select ... where exists(查询语句)
    exists:当查询结果不为null,返回true
      当查询结果为null,返回false
    
    */
    --1.查询出有员工的部门
    
    select * from dept where exists(select * from emp where dept.deptno = emp.deptno)
    
    select * from dept where not exists(select * from emp where dept.deptno = emp.deptno)
    
    select * from emp where 1=1;
    select * from emp where exists(select * from dept where deptno = 199);
    

    Oracle数据类型

    字符类型

    • char固定长度类型
    • varchar2可变长度类型,可保存1333多个汉字

    数值类型

    • number(3)最大可表示999

    • number(3,2)小数点后两位,共3位

    日期类型

    • date时间,MySQL中为年月日,Oracle中精确到时分秒,相当于MySQL中的datetime
    • timestamp精确到秒的后9位

    大数据类型

    • long大数据字符类型,2G
    • Clob存放字符类型,4G
    • Blob:存放二进制类型,4G

    约束

    • 主键约束(自定义主键名constraint PK_PID primary key(pid))
    • 非空约束(not null)
    • 唯一约束(unique,可以有多个null)
    • 检查约束(gender number check(gender in (1,0)))
    • 外键约束(constraint FK_ORDER_ORDER_ID foreign key(order_id) references orders(order_id))

    事务

    • 需要手动提交:commit;
    • 可设置回滚点:savepoint p1;
    • 回滚到回滚点:rollback to p1;
    • 默认隔离级别:读已提交

    视图

    就是封装了一条复杂查询的语句,是一个虚拟的表,本身不存放数据,数据来源于原始表,最大的优点就是简化复杂查询

    -- 创建视图
    create [or replace] view 视图名 as sql查询语句;
    -- 查询视图
    select * from emp_view;
    -- 修改视图中的某条记录的值,实际是修改了原始表中的数据 同样也可以删除 所以通常创建只读视图
    update emp_view set ename = 'smith' where empno = 7369;
    commit;
    -- 删除视图
    drop view emp_view;
    -- 创建只读视图 with read only
    create [or replace] view 视图名 as sql查询语句 with read only;
    

    序列

    -- 类似于MySQL的自sssfsdfs增长
    create sequence seq_test -- 通常写到这里即可
    start with 5
    increment by 2
    maxvalue 20
    cycle
    cache 5
    -- 查询序列
    select seq_test.currval from dual;
    select seq_test.nextval from dual;-- 插入数据的时候可以直接用这个 seq_test.nextval
    -- 删除序列
    drop sequence seq_test;
    

    索引

    create table person(
        pid number,
        pname varchar2(50)
    )
    --创建500万条的数据 4:43
    create sequence seq_person;
    begin
       for i in 1..5000000 loop
        insert into person values(seq_person.nextval,'测试数据'||i);
       end loop;
       commit;
    end;
    select * from person;
    -- 1.063s 0.5s 第二次查有缓存  建索引之后0.344s
    select * from person where pname ='测试数据4789789';
    -- 2:51s
    create index person_index on person(pname);
    -- 建联合索引不要超过4列
    -- 主键自带索引
    

    同义词

    为表创建别名,不需要dba权限就可以创建同义词

    -- 创建
    create public synonym 同义词名 for 目标表名
    -- 删除
    drop public synonym 同义词名
    

    导入导出

    -- PLSqlDeveloper的导入导出方式参照Oracle导入导出.docx
    -- 全库导出
    exp 用户名/密码 full=y file=expdat.dmp
    -- 全库导入
    imp system/orcl full=y file=expdat.dmp
    -- 按用户导出
    exp scott/tiger file=expdat.dmp
    -- 按用户导入
    imp scott/tiger file=expdat.dmp full=y
    --用plsql->tools->export更方便!!
    

    PL/SQL编程语言

    过程化语言procedure language(其实就是存储过程的语法)

    -- 各种变量
    -- 冒号等于就是赋值符号
    -- 等于就是等等与 比较运算符
    select * from emp for update;-- 锁表操作数据
    nvl(comm,0) -- 处理null值
    
    declare
      PI constant number := 3.14 -- 定义常量
      pemp emp%rowtype; -- 定义记录型变量
      pname emp.ename%type; -- 定义引用型变量
    begin
      select * into pemp from emp where empno = 7499; -- into 给记录型变量赋值
      dbms_output.put_line('员工编号:' || pemp.empno || ',员工姓名' || pemp.ename);
      select ename from into pname from emp where empno = 7499;
      dbms_output.put_line(pname);
    end;
    
    
    -- 判断分支语句
    -- 从控制台输入一个数字
    declare
      age number := &age;
    begin
      if age = 1 then -- 多个条件可以用and连接
        dbms_output.put_line('我是1');
      elsif age = 2 then
        dbms_output.put_line('我是2');
      else
        dbms_output.put_line('我不是1也不是2');
      end if;
    end;
    
    -- 循环语句
    -- 方法1
    declare
      i number := 1;
    begin
      while i <= 10 loop
        dbms_output.put_line(i);
        i := i + 1;
      end loop;
    end;
    
    -- 方法2 (常用)
    declare
      i number := 1;
    begin
      loop
        i := i + 1;
        exit when i > 10;
        dbms_output.put_line(i);
      end loop;
    end;
    
    -- 方法3
    create table person(
        pid number,
        pname varchar2(50)
    )
    --创建500万条的数据 4:43
    create sequence seq_person;
    begin
       for i in 1..5000 loop
        insert into person values(seq_person.nextval,'测试数据'||i);
       end loop;
       commit;
    end;
    
    -- 游标  多年前玩过 下次碰到了再贴进来
    -- cursor
    
    -- sql系统异常&自定义异常
    -- 有缘再玩
    
    -- 存储过程 close 再玩
    -- Java调用存储过程connection.prepareCall();//registerOutP
    
    -- 函数 再玩
    
    -- 触发器trigger,玩过,影响性能
    -- for each row   :new.empno :old
    

    教程|SQL(密码vkm6)|参考(空了再整理)

    击石乃有火,不击元无烟!!
  • 相关阅读:
    数据库注意事项
    SQL函数
    2019 SDN阅读作业(2)
    2019 SDN上机第五次作业
    2019 SDN上机第四次作业
    2019 SDN阅读作业
    2019 SDN上机第三次作业
    mysql使用记录
    2019 SDN上机第二次作业
    2019 SDN上机第一次作业
  • 原文地址:https://www.cnblogs.com/rain2020/p/14141367.html
Copyright © 2011-2022 走看看