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)|参考(空了再整理)

    击石乃有火,不击元无烟!!
  • 相关阅读:
    格式化数字,将字符串格式的数字,如:1000000 改为 1 000 000 这种展示方式
    jquery图片裁剪插件
    前端开发采坑之安卓和ios的兼容问题
    页面消息提示,上下滚动
    可以使用css的方式让input不能输入文字吗?
    智慧农村“三网合一”云平台测绘 大数据 农业 信息平台 应急
    三维虚拟城市平台测绘 大数据 规划 三维 信息平台 智慧城市
    农业大数据“一张图”平台测绘 大数据 房产 国土 农业 信息平台
    应急管理管理局安全生产预警平台应急管理系统不动产登记 测绘 大数据 规划 科教 三维 信息平台
    地下综合管廊管理平台测绘 大数据 地下管线 三维 信息平台
  • 原文地址:https://www.cnblogs.com/rain2020/p/14141367.html
Copyright © 2011-2022 走看看