Oracle专题三之Oracle基础操作、DDL/DCL/DML以及约束和常用函数

Oracle基础操作

  • 查看进程
    ps –ef | grep ora

  • 登陆数据库
    sqlplus sys/123456 as sysdba
    sqlplus scott/tiger@db88

  • 切换用户
    conn username;

  • 查看用户
    show user; 查看当前登录用户
    select username from user_users; 以 user开头的:当前用户可以,它只能看当前信息
    select username from dba_users; 以 dba开头的:只有dba权限的才能看,sys用户和system用户
    select username from all_users; 以 all开头的:权限内所有的

  • 修改密码
    password scott
    alter user scott identified by 新密码

  • 锁定用户
    alter user scott account lock;
    alter user scott account unlock;

  • 查看当前用户的table
    select table_name from user_tables;

  • 视图
    视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改。
    视图基于的表称为基表。视图是存储在数据字典里的一条select语句。
    通过创建视图可以提取数据的逻辑上的集合或组合。
    create view v_tt as select owner,object_id from all_objects where object_id<1000;

    视图的优点:
    (1)对数据库的访问,因为视图可以有选择性的选取目标表里的一部分。
    (2)用户通过简单的查询可以从复杂查询中得到结果。
    (3)维护数据的独立性,视图可从多个表检索数据。
    (4)对于相同的数据可产生不同的视图。

  • 动态性能视图
    以v$ 开头的叫 动态性能视图(v$database)

  • 查看服务器状态
    select open_mode from v$database;

  • 查看实例名
    select instance_name from v$instance;

  • 数据字典
    select * from dict;
    X$ oracle数据库核心部分,加载数据库时即被使用,加密命名【一般不会更改、也不会查看,当前库自己使用】
    加载数据库中,得调用一些数据库信息,这些数据会驻留在内存中,这些调用比较多,以表形式存在
    select * from dict where table_name='USER_TABLES';

  • 脚本执行
    @/home/oracle/a.sql

常用函数

  • as给列以别名显示:
    select username as 别名 from t_user;(这里的as关键字可以省略)
  • distinct去掉重复的行:
    select distinct username from t_user;
  • 使用运算符:
    select age+10 from t_user;
  • in匹配集合中的任意值 (any all exists)
    select * from t_user where username in('aa','bb');
  • like模糊查询:%匹配0个或多个任意字符,_匹配1个任意字符。
    select * from t_user where username like '%aaa%';
  • null判断某列为空
    select * from t_user where sex is null; (is not null)
  • order by排序:ASC: 升序排列(可以省略),DESC: 降序排列
    升序:select u.userid,u.username from t_user u order by u.userid;
    降序:select u.userid,u.username from t_user u order by u.userid desc;
  • 系统函数
    AVG–求平均值,COUNT–统计记录数,MAX–最大值,MIN–最小值,SUM–求和
    select min(userid),max(userid) from t_user;
    select count(*) from t_user;
    select count(sex) from t_user; (不为空的记录数)
    select count(distinct sex) from t_user;(不为空且不重复)
  • group by分组
    group by有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面
    select deptno,count() from emp group by deptno;
    select sex,age,count(
    ) from t_user group by sex,age;
  • having过滤分组:
    select username from t_user group by username having count(*) >=2;
  • 伪列
    rownum【代表行号,来标记一行,唯一的号码的】
    SELECT * FROM all_objects WHERE rownum < 100;
  • between and
    select * from t where OBJECT_ID between 51070 and 51080; 等价于下面这条语句 select * from t where OBJECT_ID >=51070 and OBJECT_ID <=51080;
  • 字符串连接
    select '表名是'||TABLE_NAME||',作用是'||COMMENTS from dict where table_name='USER_TABLES';
  • length:
    select length('##123##') len from dual;
  • LTRIM,RTRIM,TRIM【多用于处理空格】
  • TO_CHAR 是把日期或数字转换为字符串
    select sysdate from dual;
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
    select to_char(123,'9999.00') from dual;
    select to_char(12333,'$99,999.99') from dual;
    select to_char(123334444,'$999,999,999.99') from dual;
  • substr 截取函数
    select substr('12345',2,3) from dual; (从第二个字符开始,截取3个)
    select substr('123456789',-5) from dual;(截取最后5个)
  • 字符是否包含instr(string,substring,position,occurrence)
    string:代表源字符串
    substring:代表想从源字符串中查找的子串
    position:代表查找开始的位置,默认为1
    occurrence:代表查找值第几次出现,结果为字符串的位置
    没有找到,instr函数返回0.
    select substr('12345',2,3) from dual;
    select substr('123456789',-5) from dual;
    SELECT instr('syranmo','s') FROM dual; -- 返回 1
    SELECT instr('syranmo','ra') FROM dual; -- 返回 3
    SELECT instr('syran mo','a',1,2) FROM dual; -- 返回 0
  • abs 绝对值
  • round 函数 (四舍五入)
  • trunc 取整【 截掉小数点后值,不会四舍五入】
    select 3/2 from dual;
    select trunc(3/2) from dual;
  • to_date 日期时间计算
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') as nowTime from dual; //日期转化为字符串
    select to_char(sysdate,'yyyy') as nowYear from dual; //获取时间的年
    select to_char(sysdate,'mm') as nowMonth from dual; //获取时间的月
    select to_char(sysdate,'dd') as nowDay from dual; //获取时间的日
    select to_char(sysdate,'hh24') as nowHour from dual; //获取时间的时
    select to_char(sysdate,'mi') as nowMinute from dual; //获取时间的分
    select to_char(sysdate,'ss') as nowSecond from dual; //获取时间的秒
    求某天是星期几:
    select to_char(to_date('2015-05-07','yyyy-mm-dd'),'day') from dual;
    两个日期间的天数:
    select floor(sysdate - to_date('20150501','yyyymmdd')) from dual;
    select sysdate - to_date('20150501','yyyymmdd') from dual;
    select trunc(sysdate - to_date('20150501','yyyymmdd')) from dual;
    月份差:
    select months_between(to_date('03-31-2015','MM-DD-YYYY'),to_date('01-15-2015','MM-DD-YYYY')) "MONTHS" FROM DUAL;
    一年的第几天:
    select TO_CHAR(to_date('2015-2-11','yyyy-mm-dd'),'DDD'),sysdate from dual;
  • replace替换函数
    select replace('abc','b','######') from dual;
  • lpad (左添充) rpad (右填充)
    select lpad('func',7,'=') s1, rpad('func',7,'-') s2 from dual;
  • decode(实现if ..then 逻辑)
    select ENAME,decode(deptno,10,'部门1',20,'部门2',30,'部门3','其他') "所在部门" from emp; 如果deptno是10,就是部门一;20就是部门二
  • case when(实现if ..then 逻辑)
    select ename,
    case
    when sal<1000 then '挣得太少'
    when sal>1001 and sal<2000 then '挣得中等'
    when sal>2001 and sal<4000 then '挣得比较高'
    else '挣得太多'
    end
    from emp;
  • wm_concat(column)和LISTAGG:字段合并
    11.2以前可以使用wmsys.wm_concat,后来oracle取消了这个函数,改为使用LISTAGG
create table shopping(u_id  int,goods varchar2(100),num int);
insert into shopping values(1,'苹果',2);
insert into shopping values(2,'梨子',5);
insert into shopping values(1,'西瓜',4);
insert into shopping values(3,'葡萄',1);
insert into shopping values(3,'香蕉',1);
insert into shopping values(1,'橘子',3);
commit;
SELECT * FROM shopping;
select u_id, wmsys.wm_concat(goods) goods_sum  from shopping  group by u_id;
select u_id, wmsys.wm_concat(goods || '(' || num || '斤)' ) goods_sum  from shopping  group by u_id ;
select u_id,LISTAGG(goods) WITHIN GROUP (ORDER BY u_id) goods_sum  from shopping  group by u_id;
select u_id, LISTAGG(goods || '(' || num || '斤)' ) WITHIN GROUP (ORDER BY goods) goods_sum from shopping group by u_id ;
  • 左、右连接、全连接
    左外连接(Left outer join/ left join)
    右外连接(right outer join/ right join)
    全连接(full join)
  • 内联接查询 inner join on
  • 分析函数
    (1)sum函数,统计总合
    按照月份,统计每个地区的总收入
    select earnmonth, area, sum(personincome)
    from earnings
    group by earnmonth, area order by earnmonth;
    (2)rollup函数
    按照月份,地区统计收入
    select earnmonth, area, sum(personincome)
    from earnings
    group by rollup(earnmonth, area);
    (3)cube函数
    按照月份,地区进行收入总汇总
    select earnmonth, area, sum(personincome)
    from earnings
    group by cube(earnmonth, area)
    order by earnmonth, area nulls last;
    (4)grouping函数
    在以上例子中,是用rollup和cube函数都会对结果集产生null,这时候可用grouping函数来确认
    该记录是由哪个字段得出来的
    grouping函数用法,带一个参数,参数为字段名,结果是根据该字段得出来的就返回1,反之返回0
    select decode(grouping(earnmonth), 1, '所有月份', earnmonth) 月份,
    decode(grouping(area), 1, '全部地区', area) 地区,
    sum(personincome) 总金额
    from earnings
    group by cube(earnmonth, area)
    order by earnmonth, area nulls last;
    (5)rank() over开窗函数
    按照月份、地区,求打工收入排序
 select earnmonth 月份,
       area 地区,
       sname 打工者,
       personincome 收入,
       rank() over(partition by earnmonth, area order by personincome desc) 排名
  from earnings;

(6)dense_rank() over开窗函数
按照月份、地区,求打工收入排序2

select earnmonth 月份,
       area 地区,
       sname 打工者,
       personincome 收入,
       dense_rank() over(partition by earnmonth, area order by personincome desc) 排名
  from earnings;

(7)row_number() over开窗函数
按照月份、地区,求打工收入排序3

select earnmonth 月份,
       area 地区,
       sname 打工者,
       personincome 收入,
       row_number() over(partition by earnmonth, area order by personincome desc) 排名
  from earnings;

rank,dense_rank,row_number的区别:
结果集中如果出现两个相同的数据,那么rank会进行跳跃式的排名,
比如两个第二,那么没有第三接下来就是第四;
但是dense_rank不会跳跃式的排名,两个第二接下来还是第三;
row_number即使两个数据相同,排名也不一样。
(8)sum累计求和
根据月份、地区求出各个打工者收入总和,按照收入由少到多排序

select earnmonth 月份,
       area 地区,
       sname 打工者,
       sum(personincome) over(partition by earnmonth, area order by personincome) 总收入
  from earnings;

(9)max,min,avg和sum函数综合运用
按照月份和地区求打工收入最高值,最低值,平均值和总额

  select distinct earnmonth 月份,
                area 地区,
                max(personincome) over(partition by earnmonth, area) 最高值,
                min(personincome) over(partition by earnmonth, area) 最低值,
                avg(personincome) over(partition by earnmonth, area) 平均值,
                sum(personincome) over(partition by earnmonth, area) 总额
  from earnings;

(10)lag和lead函数
lag和lead函数可以在一次查询中取出某个字段的前N行和后N行的数据(可以是其他字段的数据,比如根据字段甲查询上一行或下两行的字段乙)
求出每个打工者上个月和下个月有没有赚钱(personincome大于零即为赚钱)

 select earnmonth 本月,
       sname 打工者,
       lag(decode(nvl(personincome, 0), 0, '没赚', '赚了'), 1, 0) over(partition by sname order by earnmonth) 上月,
       lead(decode(nvl(personincome, 0), 0, '没赚', '赚了'), 1, 0) over(partition by sname order by earnmonth) 下月
  from earnings;
  • 行列转换
create table TEST_TB_GRADE 
( 
ID NUMBER(10) not null, 
USER_NAME VARCHAR2(20 CHAR), 
COURSE VARCHAR2(20 CHAR), 
SCORE FLOAT
);
insert into TEST_TB_GRADE values(1,'michael','语文',78);
insert into TEST_TB_GRADE values(2,'michael','数学',95);
insert into TEST_TB_GRADE values(3,'michael','英语',81);
insert into TEST_TB_GRADE values(4,'xiaoxiao','语文',97);
insert into TEST_TB_GRADE values(5,'xiaoxiao','数学',78);
insert into TEST_TB_GRADE values(6,'xiaoxiao','英语',91);
insert into TEST_TB_GRADE values(7,'zhangsan','语文',80);
insert into TEST_TB_GRADE values(8,'zhangsan','数学',55);
insert into TEST_TB_GRADE values(9,'zhangsan','英语',75);
insert into TEST_TB_GRADE values(10,'lisi','语文',87);
insert into TEST_TB_GRADE values(11,'lisi','数学',65);
insert into TEST_TB_GRADE values(12,'lisi','英语',75);
commit;
SELECT * FROM TEST_TB_GRADE;

行转列

select t.user_name, 
sum(decode(t.course, '语文', score,null)) as CHINESE, 
sum(decode(t.course, '数学', score,null)) as MATH, 
sum(decode(t.course, '英语', score,null)) as ENGLISH 
from test_tb_grade t 
group by t.user_name 
order by t.user_name;
select t2.SCORE_GP, 
  sum(decode(t2.course, '语文', COUNTNUM,null)) as CHINESE, 
  sum(decode(t2.course, '数学', COUNTNUM,null)) as MATH, 
  sum(decode(t2.course, '英语', COUNTNUM,null)) as ENGLISH 
from ( 
  select t.course, 
         case when t.score  <60 then '00-60'
              when t.score >=60 and t.score <80  then '60-80'
              when t.score >=80 then '80-100' end as SCORE_GP, 
         count(t.score) as COUNTNUM 
  FROM test_tb_grade t 
  group by t.course,  
        case when t.score  <60  then '00-60'
              when t.score >=60 and t.score <80  then '60-80'
              when t.score >=80 then '80-100' end
  order by t.course ) t2 
group by t2.SCORE_GP 
order by t2.SCORE_GP;

列转行

CREATE TABLE TEST_TB_GRADE2 AS
select t.user_name USER_NAME, 
sum(decode(t.course, '语文', score,null)) as CN_SCORE, 
sum(decode(t.course, '数学', score,null)) as MATH_SCORE, 
sum(decode(t.course, '英语', score,null)) as EN_SCORE 
from test_tb_grade t 
group by t.user_name 
order by t.user_name;
commit;
SELECT * FROM TEST_TB_GRADE2;
select user_name, 'CN_SCORE' COURSE, CN_SCORE as SCORE from test_tb_grade2
union
select user_name, 'MATH_SCORE' COURSE, MATH_SCORE as SCORE  from test_tb_grade2
union
select user_name, 'EN_SCORE' COURSE, EN_SCORE as SCORE  from test_tb_grade2
 order by user_name, COURSE;

DCL

  • Data Control Language,数据控制语言:用于定义数据库用户的权限。DCL包括
    GRANT 授权
    REVOKE 回收权限
    deny 拒绝授予主体权限。防止主体通过其组或角色成员身份继承权限
  • GRANT 赋于权限
    常用的系统权限集合有以下三个:
    CONNECT(基本的连接)=许多个权限, RESOURCE(程序开发), DBA(数据库管理)
    常用的数据对象权限有以下五个:
    ALL ON 数据对象名, SELECT ON 数据对象名, UPDATE ON 数据对象名,
    DELETE ON 数据对象名, INSERT ON 数据对象名, ALTER ON 数据对象名
    操作
    GRANT CONNECT, RESOURCE TO 用户名;
    GRANT SELECT ON 表名 TO 用户名;
    GRANT SELECT, INSERT, DELETE ON表名 TO 用户名1, 用户名2;
  • REVOKE 回收权限
    REVOKE CONNECT, RESOURCE FROM 用户名;
    REVOKE SELECT ON 表名 FROM 用户名;
    REVOKE SELECT, INSERT, DELETE ON 表名 FROM 用户名1, 用户名2;
  • 示例
    1、创建用户test2,密码也是test2(记得最有以分;号结束):
        create user test2 identified by test2;
    2、给test2授权:create session;(允许用户登陆Oracle):
        grant create session to test2;
    3、给test2分配创建表的权限;
        grant create table to test2;
    4、给test2分配表空间的使用权限;
        grant unlimited tablespace to test2;
    5、收回test2用户的create session权限
       revoke create session  from test2;   
    6、收回test2用户的create table、unlimited tablespace权限
       revoke create table,unlimited tablespace  from test2; 

DDL

  • Data Definition Language
    数据定义语言: 用于定义数据的结构,比如 创建、修改或者删除数据库对象。
    DDL包括:DDL语句可以用于创建用户和重建数据库对象。下面是DDL命令:
    CREATE 创建
    ALTER 修改
    DROP TRUNCATE 删除
  • 创建表
create table t_user
(
      userid number(30),
      username varchar2(20),
      age number(3),
      sex varchar(2)
);    
  • 删除表
    drop table t_user;
  • 修改字段长度
    alter table t_test modify username varchar2(10);
    desc t_test;

DML

  • Data Manipulation Language
    数据操作语言:用于检索或者修改数据。
    DML包括: SELECT:用于检索数据;
    INSERT:用于增加数据到数据库;
    UPDATE:用于从数据库中修改现存的数据
    DELETE:用于从数据库中删除数据。
    简单示例
    insert into t_user (userid,username,age,sex) values (1,'老王',30,'男');
    commit;
    delete t_user;
    delete t_user where userid = 3;
    update t_user set username = 'aa',sex = '男';
    select···from···where···group by···having···order by···;

约束

(1)如果某个约束只作用于单独的字段,既可以在字段级定义约束,也可以在表级定义约束;但如果某个约束将作用于多个字段,必须在表级定义约束。
(2)oracle中的约束通过名称来进行识别。在定义约束时可以通过constraint关键字为约束命名。

  • 主键约束(primary key)
create table person
 (
       p_id int primary key,        --定义该字段为主键约束【字段级约束】
       p_name varchar2(20),
       p_age int
 );
create table person2
(
       p_id int constraint p_pk2 primary key,    --定义该字段为主键约束,并指定约束名字【字段级约束】
       p_name varchar2(20),
       p_age int
);
create table person3
(
       p_id int,
       p_name varchar2(20),
       p_age int,
       constraint p_pk3 primary key (p_id,p_name)--定义复合主键,并指定名字【表级约束】
);
  • 非空约束(not null)
create table person4
(
       p_id int,
       p_name varchar2(20) not null, --定义该列的非空约束
       p_age int 
 );
  • 唯一约束(unique)
create table person2
(
       p_id int,
       p_name varchar2(20) constraint gulaijing unique not null, --同时定义唯一和非空约束
       p_age int
);
  • 外键约束(foreign key)
    外键约束的特点:
    定义为外键约束的字段中只能包含相应的其他表中引用字段的值或null值。
    可以为1个字段定义外键约束,也可以为多个字段的组合定义外键约束。
    定义了外键约束的字段和相应的引用字段可以存在于同1个表中,称为自引用。
    对同1个字段可以同时定义外键和非空约束。
    主表中的被引用列,必须有主键约束或唯一约束。
    在定义外键约束时,还可以通过on关键字来指定引用行为的类型。当主表中的一条记录被删除时,需要通过引用行为来确定如何处理子表中的外键列的值。
    delete cascade : 指删除父表记录时删除子表中所有的相关记录
    delete set null :指删除父表记录时 将所有相关记录的外部码字段值设置为NULL
    delete no action: 指删除父表记录时 不做任何操作(默认情况)
  • 检查约束(check)
create table person
(
       p_id int,
       p_name varchar2(20),
       p_age int check(p_age > 20)  
);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容