为什么结果集中就可以直接获取到错误的值
0对于创建表和列时若要是用小写那就需要加上“”,否则oracle默认大写。起别名时用双引号
系统:是管理员orcl
sys:是超级管理员
1.安装^ C退出错误状态
安装VM--安装xp操作系统(将系统复制到本机,解压.--“在虚拟机中打开主页 - ”打开虚拟机,找到解压后的xp_oracle.vmx,点击打开.--“开启次虚拟机” - “安装oracle
- ”将数据库文件夹复制到xp系统盘中 - “双击文件中的设置,开启安装 - ”第一个界面只需输入数据库口令即密码(我的为orcl) - “第二个页面,给未执行项打钩
- ”第三个页面,安装 - “第五个页面,口令管理解锁Scott和HR--”出现安装结束。
测试安装:xp中dos dos sqlplus system / orcl
安装oracle客户端:instantclient_12_1。进到sqlplus.exe所在目录中移+右键在此处打开dos窗口 - “关闭防火墙 - ”sqlplus system/[email protected]:1521 / orcl,
- “报错TNS :侦听器未在CONNECT_DAT中获得SERVICE_NAME
- “新建虚拟网卡 - ”编辑 - 虚拟网络编辑 - 添加网络,记住子网IP(241.0) - “本机多了一块虚拟网卡,查看一些新添加网卡的IP(241.1)
- “再修改xp的IP,电脑,属性,互联网协议,选择使用下面的IP,设为与新建的虚拟网卡在一个段的IP(241.11)
- ”让使用此块网卡 - >开机处xp_oracle处右击,设置,网络适配器,自定义,选择自己创建的虚拟网卡。确定。再ping一下sqlplus system/[email protected]:1521
- “报错no监听器 - “找到xp中的oracle安装路径C:\ oracle \ product \ 10.2.0 \ db_1 \ NETWORK \ ADMIN中的listener.org和tnsname.org修改为新建的虚拟网 卡的IP
- “重启xp的oracle服务 - ”先重启OracleOraDb10g_home1TNSListener服务再重启OracleServiceORCL服务 - “再连接sqlplus system/[email protected]:1521/orgl
安装可视化界面:PLSQL Developer10.0.0.1963安装目录不要有中文和空格
配置可视化界面:打开,暂时不输入密码选择取消 - 工具 - 首选项
- “将安装oracle目录下的sqlplus.exe(D: \ oracle \ instantclient_12_1)
和ocl.exe(D:\ oracle \ instantclient_12_1 \ oci.dll)所在的路径粘到两个格中。关闭重启多了一个连接
- “配置一下数据库下拉框将oracle安装路径C :\ oracle \ product \ 10.2.0 \ db_1 \ NETWORK \ ADMIN中的tnsname.ora粘贴到本机的安装目录下,
将其在的目录配置到本机环境变量里面。新建文件夹TNS_ADMIN,将路径D :\ oracle \ instantclient_12_1粘进去。重启
使用:打开SQL窗口,右击新的SQL窗口
2若安装到本机上,需要修改一个属性.exe文件右击 - “属性 - ”兼容性 - “勾选以兼容性运行这个程序 - ”勾选以管理员身份运行。再运行EXE文件,右键以管理员身份运行。
2.oracle体系结构
数据库:database
oracle只有一个数据库orcl故无需创建数据库
实例:由一系列的内存结构和服务组成,甲骨文数据库中可以有多个实例几乎都是只有一个实例把实例当成数据库理解有几个实例,服务里就有几个XXXorcl服务。
数据文件: .dbf存放数据的文件物理文件
表空间:数据文件的逻辑映射
用户:管理表空间的人
重置密码:scott用户的密码是tiger但是初次打不开,需重置Scott
重置用户的密码的SQL语句,提醒用户Scott用老虎识别; 解锁用户的语句:alter user用户名account unlock解锁
用户:
alter user scott account unlock
4.Scott的表
------------- scott用户表内容---------------------
改变用户scott by tiger; - 修改密码
alter user scott account unlock; - 解锁用户
select * from dept; - 部门表
select * from emp; - 员工表
select * from salgrade; - 工资等级
5.基本查询
别名:别名若为字符串使用双引号,字符则不需使用。
乱码问题解决,文档找里有步骤
中文English乱码问题解决
1.查看服务器端编码
选择USERENV从双( '语言');
我实际查到的结果为:AMERICAN_AMERICA.ZHS16GBK
2.执行语句SELECT * FROM V $ NLS_PARAMETERS
查看第一行中PARAMETER项中为NLS_LANGUAGE对应的VALUE项中是否和第一步得到的值一样。
如果不是,需要设置环境变量。
否则PLSQL客户端使用的编码和服务器端编码不一致,插入中文时就会出现乱码。
3.设置环境变量
计算机 - >属性 - >高级系统设置 - >环境变量 - >新建
设置变量名:NLS_LANG,变量值:第1步查到的值,我的是AMERICAN_AMERICA.ZHS16GBK
4.重新启动PLSQL,插入数据正常
四则运算:若null参与运算结果恒为null
nvl()函数:
nvl(comm,0):当comm为null时,取值0
选择empno,ename,sal,comm,sal * 12 + nvl(comm,0)来自emp;
去重:distinct
select distinct job from emp;
字符串的连接:concat或者||
把员工的信息显示一句话:员工编号是xx,姓名是XXX,职位是XXX
选择'员工编号是'|| empno,',姓名是'|| ename,',职位是'emp from emp
select'员工编号是'|| empno || ',姓名是'|| ename ||',职位是'来自emp的工作
6.条件查询in,not in,is not null,is null不等于0(<>或!= 0)包括临界值
1查询职位是CLERK的员工select * from emp where job ='CLERK'
2查询职位是CLERK的并且部门是30的员工select * from emp where job ='CLERK'和deptno = 30
3查询职位是CLERK的或者部门是30的员工select * from emp where job ='CLERK'或deptno = 30
4查询工资大于1500并且小于3000的员工select * from emp其中sal> = 1500且sal <= 3000;
select * from emp其中sal在1500和3000之间; - 包括临界值
select * from emp其中sal在3000和1500之间; - 无结果
select * from emp其中sal不在1500和3000之间; -包括临界值
select * from emp where ename not in in('SMITH','JONES','SCOTT');
5查询编号是7369 7566 7788的员工select * from emp where empno in(7369,7566,7788);
6查询姓名是SMITH,JONES,SCOTT的员工select * from emp where ename in('SMITH','JONES','SCOTT');
7查询奖金不为空的员工select * from emp其中comm不为null且comm!= 0;
select * from emp其中comm不为null且comm <> 0;
8模糊查询姓名中带_的要使用转义字符:
代表转义的字符有:q,5 @ _而%&不能使用
select * from emp where ename like'%q _%'escape'q'(此处的_是字段中带的值如“我_是”)
9排序:语句此出现在求最后
按照奖金从高到低排序.ASC降序空值最后/第一(值为空的数据的位置)
SELECT * FROM通过COMM降序零点EMP顺序最后的
SELECT * FROM EMP为了通过通讯降序COMM ;
首先通过comm asc nulls从emp order中选择*
7.函数
单行函数:作用域多少条,结果多少条。
伪表:双没有实际意义目的就是配合查询产生一条结果.oracle可以无形式查询
选择1 + 1来自emp;有多少条记录产生多少条结果为2的记录。
从双重中选择1 + 1; 产生一条结果为2记录的
字符函数:
replace--替换
选择替换从双( 'JAG', 'A', 'XXX'): 'JAG'中的一个替换成XXX
substr--截取开始位置0和1是一样的
select substr('abcde',2)from dual:'abcde'取出'bcd'索引从1开始,但是0 1是一样值第一个值
concat--连接只能有两个参数
选择'aaa','bbb'来自双重
选择'aaa'||
'bbb'来自双重选择concat('aaa','bbb')来自双重:
长度
选择长度('qwer')来自双
数值函数:
round:四舍五入
select round(56.349)from double
select round(56.349,2)from dual:保留两位小数
select round(56.349,-1)from dual:四舍五入后再对小数点前的第几位进行四舍五入
trunc:截断
select trunc(56.349)from dual 56:不四舍五入直接截断
select trunc(56.349,2)from dual:保留两位小数65.34
select trunc(56.349,-1)from dual:对小数点前的第几位进行截破50
mod:取余
选择mod(10,2)来自双
选择mod(10,0)来自double:值为10
日期函数:
获取当前时间
MySQL:现在选择
oracle:从双
add_months中选择sysdate
months_betwee
时间 - 时间=数值数值的英文单位天
时间+数值=时间
查询三个月后的日期
ADD_MONTHS(时间,数值(可正可负))
选择ADD_MONTHS(SYSDATE,3)从双
时间是可以相加减的
sysdate-当前时间时间 - 时间=数值数值的单位是:天
时间+数值=时间
计算员工入职的天数
选择empno,ename,hiredate,sysdate-hiredate来自emp
months_between
计算员工入职的月数月_之间
选择empno,ename,hiredate,months_between(sysdate,hiredate)来自emp
转换函数:
to_date:查询1980-01-01到1985-12-31入职的员工
SQL:select * from emp在'1980-01-01'和'1985-12-31'之间雇用
to_date:select * from emp where todate to todate('1980-01-01','yyyy-MM-dd')and to_date('1985-01-01','yyyy-MM-dd')
to_char:将日期转换为字符串
to_char:
to_char(sysdate,'yyyy-MM-dd hh:mi:ss')yyyy:年MM(mm):月dd:日hh:小时mi:分ss:秒日:星期
从双
to_char中选择to_char(sysdate,'yyyy-MM-dd'):从双 to_char中选择to_char(sysdate,'yyyy-MM-dd hh:mi:ss')
:select to_char(sysdate,'yyyy'),来自双重的to_char(sysdate,'mm'),to_char(sysdate,'dd'),to_char(sysdate,'day')
查询1980和1985入职的员工:select * from emp where to_(hiredate,'yyyy')='1980'or to_char(hiredate,'yyyy')='1985';
to_number :(用不用都可以)
从双重选择'23'+'23';
从dual中选择to_number(“23”)+ to_number(“23”);通过
函数:
nvl:处理空值
解码:类似于条件表达式对于作业字段的职员显示为业务员。
选择作业,解码(作业,' CLERK','业务员','销售员','销售','其他')来自emp;
表达式:(重点)对于工作字段的职员显示为业务员。
案例字段当值然后显示的值... 。
选择工作,选择工作时'CLERK'然后'业务员'当'SALESMAN'然后'业务员'其他'
多行函数:(又叫聚合函数,组函数)不管作用域是多行,但是产生一条结果
count sum avg max min
select count(*)from emp
D2多表查询
1.多表查询一般要是用别名
2.对于多表的连接,分左外连接和右外连接,即全量表和非全量表,若要让没有的数据显示出来,在少的一次加上“(+)”等同于左连接,右加入等价,'(+)'加在左,左外连接。
3.若返回多行多列的子查询,将其当做表来使用。
1笛卡尔积范例
:查询员工表和部门表
select * from emp e,dept d其中e.deptno = d.deptno --56
select * from emp e; --14
选择*来自dept d; - 4
范例:查询出雇员的编号,姓名,部门的编号和名称,地址
选择e.empno,e.ename,d.deptno,d.dname,d.loc来自emp e,dept d where e.deptno = d.deptno
2自关联自连接
范例:查询出每个员工的上级领导(员工编号,员工姓名,员工部门编号,员工工资,领导编号,领导姓名,领导工资)
选择e1.empno,e1.ename,e1.deptno ,e1.sal,e2.empno,e2.ename,e2.sal来自emp e1, - 员工表emp e2 - 领导表,其中e1.mgr = e2.empno
范例:在上一个例子的基础上查询该员工的部门名称
选择e1.empno,e1.ename,d.dname,e1.sal,e2.empno,e2.ename,e2.sal来自
emp e1, - 员工表
emp e2, - 领导表
dept d - 部门表
其中e1.mgr = e2.empno和e1.deptno = d.deptno
范例:查询出每个员工编号,姓名,部门名称,工资等级和他的上级领导的姓名,工资等级
select * from salgrade
从
emp e1中选择e1.empno,e1.ename,d.dname,e1.sal,s1.grade,e2.empno,e2.ename,e2.sal,s2.grade , - 员工表
emp e2, - 领导表
部门,部门表
salgrade s1, - 工资等级表
salgrade s2
其中e1.mgr = e2.empno和e1.deptno = d.deptno
和e1.sal在s1.losal和s1.hisal
和e2.sal之间在s2.losal和s2.hisal之间
3外链接左外连接右外连接
右连接
emp e1 - 全量表
emp e2 - 非全量表
select e1.empno,e1.ename,e1.deptno,e1.sal,e2.empno,e2.ename,来自emp e1的e2.sal,emp e2,其中e1.mgr = e2.empno(+)
左连接
选择e1.empno,e1.ename,e1.deptno,e1.sal,e2.empno,e2.ename,e2.sal来自emp e1左连接emp e2 on e1.mgr = e2.empno
查询出所有的部门下的员工,要求把没有员工的部门也展示出来
select * from emp e,dept d where e.deptno(+)= d.deptno --56
select * from dept d left join emp e on e.deptno = d.deptno
4子查询
查询比SCOTT工资高的员工
select * from emp where sal>(从emp中选择sal,其中ename ='SCOTT')
查询出和SCOTT同部门并且同职位的员工
select * from emp where deptno =(选择deptno from emp where ename ='SCOTT')和job =(从emp中选择作业ename ='SCOTT');
******* select * from emp where(deptno,job,sal)=(select deptno,job,sal from emp where ename ='SCOTT'); *******
查询每个部门的最低工资对应的雇员信息(包括部门名称)若返回多行多列的子查询,将其当做表来使用
从e e选择e。*,d.dname,
(选择deptno,min( sal)来自emp group的minsal by deptno)t,
dept d
其中e.sal = t.minsal和e.deptno = t.deptno和e.deptno = d.deptno
查询出不是领导的员工
select * from emp where empno not in(select empr mgr from emp where mgr not null)
5分页引入
rowid:每行数据的物理地址rownum:每行数据的序号,但是不支持大于号序号是随着查询产生的每次查询完之后都有这两个列属性,只是是隐藏的。
查询员工表中工资最高的前三名
选择e。*,rowid,rownum来自emp e,其中rownum <4 order by sal desc
select e。*,rownum from(select * from emp order by sal desc)e where rownum < 4
6 oracle分页思想(oracle不支持大于号)
emp分页显示每页显示3条
第一页
select e。*,rownum from(select * from emp order by sal desc)e其中rownum <4
第二页7566 7698 7782 rownum不支持大于号
select * from(select e。*,rownum r from(select * from emp order by sal desc)e其中rownum <7)t其中tr> 3
练习:找到员工表中薪水大于本部门平均薪水的员工
select * from emp e,(选择deptno,avg(sal)avg from emp group by deptno)s其中e.sal> s.avg和e.deptno = s .deptno
统计每年入职的员工个数
select to_char(hiredate,'yyyy')years,count(*)from emp group by to_char(hiredate,'yyyy')
7行转列
1,别名
从双
2中选择2“1980” ,解码
解码(列,列的值,显示的值)
select sum(t.counts)“Total”,sum(decode(years,'1980',count))“1980”,sum(decode(years,'1981',count))“1981”,sum(decode(years) ,'1982',计数))“1982”,
sum(解码(年,'1987',计数))“1987”来自(select to_char(hiredate,'yyyy')年,count(*)计数来自emp group by to_char(hiredate,'yyyy'))t
8子查询总结从子查询中选择子查询,其中子查询组通过子查询
1,子查询可以返回单行单列值
2,子查询可以返回单行多列值
3,子查询可以返回多行多列值(通常把子查询的结果当成表来使用)
4,使用子查询可以提高查询效率
5,子查询可以出现在SQL语句的任何位置
6,查询比较
emp 10000
dept 1000
查询部门编号是10的员工
1000W select * from emp e,dept d其中e.deptno = d.deptno和d.deptno = 10
1W select * from emp e,(select * from dept其中deptno = 10)d其中e.deptno = d.deptno产生笛卡尔积比较少。
----------------------------以上都是重点------------------ ---------
9存在比执行效率高select * from tablename where exists(sql查询语句)
存在(sql查询语句)sql查询语句查询无结果存在(sql查询语句)返回结果是false
存在(sql查询语句)sql查询语句查询有结果存在(sql查询语句)返回结果是真
select * from emp where exists(select * from dept where deptno = 1)
select * from emp,其中1 = 2
select * from emp where exists(select * from dept where deptno = 10)
select * from emp,其中1 = 1
查询没有员工的部门select * from dept d where not exists(select * from emp e where d.deptno = e.deptno)
select * from dept d其中d.deptno不在(从emp中选择deptno)
10集合运算
集合运算时两个结果集只要是列的数量相等并且对应的列数据类型一致就可以做集合运算
union --all--并集
intersect - 交集
减 - 减差集补集
范例:工资大于1500,或者是20号部门下的员工select * from emp其中sal> 1500或deptno = 20;
范例:工资大于1500,并且是20号部门下的员工select * from emp其中sal> 1500和deptno = 20;
范例:1981年入职的普通员工(不包括总裁和经理)
select * from emp其中to_char(hiredate,'yyyy')='1981'
select * from emp where job ='MANAGER'或job ='PRESIDENT'
D3
1 DDL数据库表操作
1 MySQL 与 oracle 比较
MySQL oracle
1 创建数据库 创建表空间同时把数据文件也创建
2 创建表 创建用户
3 操作数据 赋权限
4 操作数据 操作数据
2 oracle常见的数据类型
字符型: 没有默认值必须设置长度
char: 固定长度 最大长度255 相当于MySQL中的char
varchar2: 不固定长度 最大长度3999 varchar
数值型: 默认是8
number number(3)999(总共三位) number(3,2) 9.99(总共三位,两位小数) 总长度不包括小数点和负号
日期型: (MySQL中的date只有年月日 但是datetime有时分秒)
date: 相当于MySQL中的datetime 有十分秒
timestamp: 精度高 最多可以保留到秒后9位小数
大数据类型:(了解)
long:支持2G相当于mysql的longtext
clob:支持4G
blob:支持4G
3 oracle约束:
主键:主键
非空;非空;
唯一:唯一
外键:外键(外键)
检查:check(性别在(0,1))表示此字段只能是0,1
没有主键自增但是有序列
4 oracle使用
1创建表空间,同时将数据文件创建
create tablespace heima_50_space - 指定表空间名称
datafile'C://heima_50.dbf' - 创建数据文件
size 100M - 给数据文件指定大小
autoextend on -给数据文件设置自动增长
next 10M - 自动增长大小
2创建用户user
create user heima_50 - 创建用户
由heima_50识别 - 给用户指定密码
默认表空间heima_50_space - 用户默认操作的表空间
3赋权限
授予dba到heima_50 - 把dba的角色赋予heima_50
select * from session_privs - 查看当前用户权限oracle内置角色dba资源连接
4操作表创建drop table
创建表:
create table person(pid number(5)主键,pname varchar2(30),性别编号(1),tele varchar2(11),
约束pk_pid主键(pid),//给主键添加一个约束,约束名叫pk_pid
约束check_gender检查(性别在(0, 1)),//给检查添加一个约束,约束名叫check_gender
约束unique_key unique(tele))//给Tele添加一个约束,约束名叫unique_key
//非空约束不需要别名
添加列:
alter table person add(address varchar2(30))
删除表:drop如果是create创建的,都要用drop删除
drop table person
修改数据:update表名set字段1 =值,字段2 =值where where条件。
外键:外键
create table orders(oid number(5)primary key,totalprice number(8,2))
create table orderdetail(odid number主键,价格编号(8,2),名称varchar2(30),oid编号(5),
约束fk_orderdetail_orders外键(oid)引用订单(oid)
快速建表语句:
从scott.emp创建表emp作为select *
5 数据操作 select insert update delete -- 但是后三个涉及事务 savepoint 事务保存点,记录当前事务的状态,以便回滚使用
rollback to; 回滚到哪
事务保存点的使用:在属于同一个事务的情况下可以使用事务保存点 commit;提交
电子项目用户注册
1,记录日志表插入operation_log
保存点a
2,插入用户数据插入用户
3,发送手机验证码插入user_code发生错误 - 回滚回滚到
插入数据:oracle的事务是外露的
insert into person values();
commit
insert into person(字段1,字段2)values(1,2);
删除:
delete
delete from person删除全部数据
truncate删除全部数据
效果等于从人物中删除
区别:
删除只是删除数据而截断是摧毁表后重新创建表
删除删除的数据可以回滚,截断不可回回
删除会产生磁盘碎片,截断不会产生磁盘碎片
修改数据更新表名设置字段1 =值,字段2 =值条件
给NEW YORK的员工涨100元工资
更新emp set sal = sal + 100 where deptno in(select deptno from dept where loc ='NEW YORK')
5数据库中的其他对象
视图(查看)重点
1一个虚表(如果是普通视图的话,修改视图的表,原表的字段也修改,可以创建只读视图)
2作用:可以封装复杂的SQL查询语句
可以隐藏敏感列
3语法:
创建视图视图名作为SQL查询语句但是可以通过视图修改表
创建或替换视图view_emp作为SQL查询语句创建或者替换表要
替换的表名新表名创建或替换视图view_emp作为选择empno ,ename,job,mgr,hiredate,deptno from emp with read only
序列序列重点
序列:主要是用来做主键自增的,他是独立于表之外的对象类似于autoincreamt
创建简单语法:create sequence序列名称
create sequence seq_person;
从双下一个值中
选择seq_person.nextval从双当前值中选择seq_person.currval
使用:
insert into person(pid,pname)值(seq_person.nextval,'TOM');
select * from person
insert into orders(oid)values(seq_person.nextval);
序列的复杂语法(了解)5 7 9 11 13 15
create sequence seq_test
minvalue 1 - 默认最小值1
increment by 1 - 默认是1
start with 4 - 默认是1
maxvalue 15 - 默认值是18个9 999999999999999999
cycle - 循环默认nocycle
cache 6 - 缓存默认会缓存20
5 7 9 11 13 15 3 5 7 9 11 13 15 3 5 7 9 11 13 15
插入订单(oid)值(seq_test.nextval);
承诺;
从dual中选择seq_test.nextval
索引指重点
独立也是对象的
作用英文:提高查询效率
使用索引:
1,如果表中的数据经常被修改,不合适创建索引
2,数据量小时不用建索引
3,某些字段不会被当成条件做查询时,没有必要建索索
语法:
在表名(字段名)创建索引索引名称;
在emp(ename)上创建索引index_emp_ename给emp中的ename创建索引
对比:
---创建一个表500W条数据
创建表t_test(tid number,tname varchar2(30));
开始
对i在1..5000000
环
插入t_test值(I, '测试数据' || I);
结束循环;
结束;
select * from t_test where tname ='测试数据4000000'--0.734s
在t_test(tname)上创建索引index_test
select * from t_test where tname ='测试数据4560000'--0.062s
2如果提高sql的查询效率
1,创建索引
2,使用子查询
3,经常出现的列尽量做到同一个表中
4,使用分区 - 课后查询资料
3复合索引(了解)
emp
ename job
create index index_emp_ename_job on emp(ename,job)
select * from emp where job =''and ename = XX
4同义词(了解)同义词
创建公共同义词salgrade for scott.salgrade
select * from scott.salgrade
从salgrade中选择*
drop public synonym salgrade
5数据的导入导出(应用于数据库备份,整库的导入导出)
整库导出命令:exp system / itcast full = y
按照用户导入导出:(重点)
把scott用户下的所有数据导入到heima_50用户下把scott下所有东西导出(表视图索引序列等)
注意:exp imp电脑上必须本机安装Oracle软件,若没有去VM运行
在dos命令窗口中执行
1,导出
exp scott /[email protected]:1521 / orcl file = c:\ scott.dmp exp库名/密码@虚拟机xpIP / file指定导出到的路径
2,导入
imp heima_50/[email protected]:1521 / orcl file = c:\ scott.dmp full = y从哪里(file = c:\ scott.dmp full = y)导入到库(heima_50)
D4 plsql语言
1 plsql语言是对SQL语法的扩展,是面向过程的
2 plsql基本语法:
·变量常量
[declare] - 可以在此声明可以声明变量常量游标异常
begin - 逻辑处理语句
[例外] - 异常处理语句相当于try catch
end;
声明变量和常量
赋值:
1声明变量时:=赋值
2引用变量时赋值:into v_name
例子:宣告
v_tel号码(11):=&a; 弹框输入具体值
v_age number(3):= 1; :=就是赋值=相当于Java中的== Java中的声明变量--java private int age = 1;
v_name varchar2(30):='sminth';
v_sal emp.sal%type:= 100; - 引用型变量(引用了emp.sal数据类型)
v_row emp%rowtype; - 记录型变量(接收整行的数据)
v_sex常数(1):= 1; --constant常量相当于Java final
begin
v_age:= 100; 对变量重新赋值--v_sex:= 0; - 常量在此赋值会报错
选择ename,sal into v_name,v_sal from emp其中empno = 7788;
从emp中选择*到v_row,其中empno = 7788; 查询某值负给变量v_row,相当于:=
DBMS_OUTPUT.PUT_LINE(v_row.ename || || v_row.sal v_row.job); 打印变量的值system.out.prinnt()
结束;
·分支不认识&&
if条件然后
逻辑处理语句
结束if;
如果条件那么
逻辑处理语句
别的
逻辑处理语句
END IF;
if条件然后
逻辑处理语句
elsif条件然后
逻辑处理语句
......
else
逻辑处理语句
end if;
例子:
declare
v_age number(4):=&age; 如果v_age <18则
开始
,然后是
dbms_output.put_line('未成年');
elsif v_age> = 18 and v_age <= 60 then
dbms_output.put_line('成年人');
else
dbms_output.put_line('老年人');
万一;
结束;
·循环不认识++
无条件循环
循环
结束循环;
列子:
声明
v_num数字(8):= 1;
开始
循环
如果v_num> 100然后
退出; 或者当v_num> 100时退出;
万一;
DBMS_OUTPUT.PUT_LINE(v_num);
v_num:= v_num + 1;
结束循环;
结束;
有条件循环
而条件
循环
结束循环;
列子:
声明
v_num数:= 1;
开始
而v_num <= 200
循环
DBMS_OUTPUT.PUT_LINE(v_num);
v_num:= v_num + 1;
结束循环;
结束;
for
startring for变量名in starting beginning。终止值
loop
end loop;
例子: 1..100 循环中的v_num
开始 dbms_output.put_line(v_num); 结束循环; 结束; ·游标 用来接收多个对象 语法 游标的定义语法:光标游标名称是SQL语句查询 游标的使用语法: 开游标名称 环 取游标名称为记录型变量 退出时游标名称%未发现; 结束循环; 关闭游标名称
例子:打印所有员工的信息
声明
光标c_emp是select * from emp;
v_row emp%rowtype;
开始
打开c_emp;
loop
cetch c_emp into v_row;
当c_emp%notfound时退出;
DBMS_OUTPUT.PUT_LINE(v_row.ename || '---' || v_row.job);
结束循环;
关闭c_emp;
结束;
- 打印指定部门的员工的信息
声明
游标c_emp(v_no number)是从emp中选择*,其中deptno = v_no;
v_row emp%rowtype;
开始
打开c_emp(10);
环
将c_emp提取到v_row;
当c_emp%notfound时退出;
DBMS_OUTPUT.PUT_LINE(v_row.ename || '---' || v_row.job);
结束循环;
关闭c_emp;
结束;
·异常增强代码的容错性和健壮性
预定义异常
声明
v_num number(6):= 9;
v_name varchar2(1);
begin
--v_num:= 1/0; - ZERO_DIVIDE
v_name:='simth'; - 当ZERO_DIVIDE然后 v_num:= 0 时--VALUE_ERROR
异常 ; DBMS_OUTPUT.PUT_LINE(v_num); - 当VALUE_ERROR然后 当其他人然后 v_name:='s'; DBMS_OUTPUT.PUT_LINE(v_name); 结束; 自定义异常 声明 v_age number:=&age; exc_age异常; -异常的声明方式
如果v_age> 150则 开始然后
提出exc_age;
万一; 当exc_age时出现
异常 - dbms_output.put_line('年龄太大,请检查数据');' - 错误窗口的弹出oracle中-20001至-29999是错误代码,余oracle可能已经使用 raise_application_error(-20001,'年龄太大,请检查数据'); 结束;
3存储过程(procedure)用过存储过程,怎么写。存储过程文件夹里报错代表语句有错
定义:一段被命名化的plSQL语句。预编译到数据中的。
语法:
创建或替换过程存储过程名(参数1 [in] / out数据类型(不带长度)...)
as | 是 - 替代了宣布
开始
结束;
例子:用于存储过程计算指定员工的年薪使用[in]
创建或替换程序pro_yearsal(数字中的v_no)
是 - 替代了声明
v_yearsal数字(8,2);
开始
从emp中选择sal * 12 + nvl(comm,0)到v_yearsal,其中empno = v_no;
DBMS_OUTPUT.PUT_LINE( '员工年薪是:' || v_yearsal);
结束;
存储过程的使用
1,呼叫
呼叫pro_yearsal(7788);
叫pro_yearsal(7369);
2,plsql
begin
pro_yearsal(7369);
结束;
例子:用储存过程计算指定员工的年薪把计算出来的年薪放到out参数中(out参数的应用)
创建或替换过程pro_yearsal2(v_no number,v_year_sal out number)将输出数据放到v_year_sal中
是 - 替代了声明
开始
从emp中选择sal * 12 + nvl(comm,0)进入v_year_sal,其中empno = v_no;
- dbms_output.put_line('员工年薪是:'|| v_yearsal);
结束;
使用带出参数的存储过程,不能使用call方法
声明
v_yearsal number(8,2);
开始
pro_yearsal2(7788,v_yearsal);
DBMS_OUTPUT.PUT_LINE(v_yearsal);
结束;
4存储函数函数
语法:
创建或替换函数存储函数名称(参数1 [in] / out数据类型(不带长度))
返回数据类型(函数结果值的数据类型)
是| as
begin
return具体的值;
结束;
使用存储函数
声明
v_year_sal数字(8,2);
begin
v_year_sal:= func_yearsal(7788);
DBMS_OUTPUT.PUT_LINE(v_year_sal);
结束;
例子:计算指定员工的年薪
创建或替换函数func_yearsal(数字中的v_no)
返回数字
是v_sal
数字(8,2);
开始
从emp中选择sal * 12 + nvl(comm,0)到v_sal,其中empno = v_no;
return v_sal;
结束;
4存储函数和存储过程的区别
语法上不同
使用场景不同,存储函数多被存储过程调用,项目与项目中间的相互调用使用的是存储过程
存储函数可以在SQL中使用,存储过程不能再SQL中使用
从emp中选择ename,job,sal,comm,sal * 12 + nvl(comm,0),func_yearsal(empno);
5用jdbc的方式调用存储过程和存储函数(特别重要)
1 public class BaseDao {
加载驱动
静态{
try {
Class.forName(“oracle.jdbc.OracleDriver”);
} catch(ClassNotFoundException e){
e.printStackTrace();
}
}获取连接
公共静态连接getConn()抛出的SQLException {
字符串URL = “JDBC:预言:瘦:@ 192.168.241.11:1521:ORCL”;
String user =“scott”;
String password =“tiger”;
return DriverManager.getConnection(url,user,password);
}
公共静态无效CLOSEALL(RS ResultSet的,声明语句,连接康恩){
如果(RS!
rs.close();
} catch(SQLException e){
e.printStackTrace();
}
}
如果(stmt是!= NULL){
尝试{
stmt.close();
} catch(SQLException e){
e.printStackTrace();
}
}
如果(参数conn!= NULL){
尝试{
conn.close();
} catch(SQLException e){
e.printStackTrace();
}
}
}
2公共类EmpDao {
输出指定部门的员工信息
公共静态无效getEmp(龙DEPTNO){
连接con = null;
PreparedStatement pst = null;
ResultSet rs = null;
试试{
con = BaseDao.getConn();
pst = con.prepareStatement(“select * from emp where deptno =?”);
pst.setLong(1,deptno);
rs = pst.executeQuery();
while(rs.next()){
System.out.println(rs.getLong(1)+ rs.getString(“ENAME”));
}
}赶上(的SQLException E){
e.printStackTrace();
3公共类ProcedureDao {
//调用的存储过程是pro_yearsal
public static void getYearsal(Long v_no){
Connection conn = null;
CallableStatement stmt = null; // CallableStatement中的conn.prepareCall(“{call存储过程和存储函数名[(<arg1>,<arg2>,...)]}”)
//用来处理存储过程,存储函数。
长年= 0l; //设置out参数值stmt.registerOutParameter(parameterIndex,sqlType);
//stmt.registerOutParameter(2,OracleTypes.NUMBER(int类型的参数));
试试{
conn = BaseDao.getConn();
stmt = conn.prepareCall(“{call pro_yearsal2(?,?)}”); //调用存储过程
stmt.setLong(1,v_no);
stmt.registerOutParameter(2,OracleTypes.NUMBER);
stmt.execute();
yearsal = stmt.getLong(2);
System.out中。
} catch(SQLException e){
e.printStackTrace();
} finally {
BaseDao.closeAll(null,stmt,conn);
4 public class FunctionDao {
//调用的存储函数是func_yearsal(v_no in number)
public static void getYearsal(Long v_no){
Connection conn=null;
CallableStatement stmt = null;//CallableStatement中的conn.prepareCall("{?=(in类型的)call 存储过程和存储函数名[(<arg1>,<arg2>,...)]}")
//用来处理存储函数。
Long yearsal = 0l; //设置out参数值 stmt.registerOutParameter(parameterIndex, sqlType);
try {
conn= BaseDao.getConn();
stmt = conn.prepareCall("{?=call func_yearsal(?)}");//调用存函数
stmt.setLong(2, v_no);
stmt.registerOutParameter(1, OracleTypes.NUMBER);
stmt.execute();
yearsal = stmt.getLong(1);
System.out.println(yearsal);
} catch (SQLException e) {
e.printStackTrace();
} finally{
BaseDao.closeAll(null, stmt, conn);
}
5 public static void main(String[] args) {
// EmpDao.getEmp(10l);
// ProcedureDao.getyearsal(7788L);
// FunctionDao.getyearsal(7788L);
ProcedureCursorDao.getEmpInfo(10l);
}
6 游标
存储过程的out参数类型是游标
sys_refcursor:系统引用型游标
create or replace procedure pro_cursor(v_no in number,v_cursor out.sys_refcursor)
is
begin
open v_cursor for select * from emp where deptno=v_no;
end;
ResultSet rs = null;
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
//{call <procedure-name>[(<arg1>,<arg2>, ...)]}
try {
conn = BaseDao.getConn();
//procedure pro_yearsal2(v_no number,v_year_sal out number)
stmt = conn.prepareCall("{call pro_cursor(?,?)}");
stmt.setLong(1, v_no);
stmt.registerOutParameter(2, OracleTypes.CURSOR); // 对out参数指定数据类型
stmt.execute();
rs = ((OracleCallableStatement)stmt).getCursor(2);
while(rs.next()){
System.out.println(rs.getLong(1)+"--"+rs.getString("ENAME"));
}
7 触发器(trigger)(触发器删除,直接找到触发器所在的文件,直接右键删除)
检测数据变化 insert update delete
语法:
create or replace trigger 触发器名称
begin | after
insert | update | delete
on tableName
for each row
declare
begin
end;
例子:做一个触发器 ,当员工表中插入一条数据后,打印一句话 "新增一名员工"
create or replace trigger tri_emp_add
after
insert
on emp
--for each row
begin
dbms_output.put_line('新增一名员工');
end;
insert into emp (empno) values (1);
例子:2017-04-27'系统维护,不能修改员工表的数据
create or replace trigger tri_emp
before
delete or update or insert
on emp
--for each row
declare
v_dateStr varchar2(30);
begin
--1、得到今天的日期
select to_char(sysdate,'yyyy-mm-dd')into v_dateStr from dual;
--2、与'2017-04-27'比较
if v_dateStr='2017-04-27' then
--3、如果日期相等弹出错误窗口
-- -20001 -29999
raise_application_error(-20002,'2017-04-27系统维护,不能修改员工表的数据');
end if;
end;
select * from emp
delete from emp where empno=1;
update emp set ename='sdsd' where empno=1;
insert into emp(empno) values(2);
错误提示;如果输入的值比原来的少,用触发器做错误提示
create or replace trigger tri_emp_sal
before
update of sal --只是针对sal
on emp
for each row -- 如果用上了:new 或者 :old 必须使用 for each row
declare
begin
-- :new :old 伪记录
if :new.sal<:old.sal then
raise_application_error(-20003,'工资的值只能比原来的多');
end if;
end;
update emp set sal=1300 where empno=7369
update emp set sal=1200 where empno=7369
select * from emp
例子:触发器的真实应用场景
create table t_test(
tid number primary key,
tname varchar2(40)
)
create sequence seq_test
insert into t_test(tname) values('aaa');
select * from t_test
--在数据插入之前对tid赋值
create or replace trigger tri_test
before
insert
on t_test
for each row
declare
--:new :old
begin
select seq_test.nextval into :new.tid from dual;
end;
删除触发器:
alter trigger 触发器名字
8 总结
---敲一遍
--jdbc连接Oracle重点
-------Oracle4天总结--
第一天
--函数
第二天
--子查询、多表查询
第三天
--索引 视图 序列(Oracle独有的)
第四天
--jdbc连接Oracle重点
delete from dept where deptno=10
select * from dept
create table dept_bak2
as
select * from dept as of TIMESTAMP
to_timestamp('20170426 123000','yyyymmdd hh24miss');
select * from dept_bak2
递归查询:
只有oracle有MySQL只能写存储函数
递归查询:select * from 表名 start with 条件1 connect by prior 条件2
例子:select * from emp start with empno=7056 connect by prior empno = mgr;
实际使用:
1,创建表空间表空间
create tablespace erp_244_space
datafile'C:\\ erp_244.dbf'size
10M
autoextend on
next 1M
2,创建用户
创建用户erp_244
标识erp_244
默认表空间erp_244_space
3,赋权限
select * from session_privs - -
用来查看当前用户的权限授予dba到erp_244
步骤一:删除用户
丢弃用户××cascade
说明:删除了用户,只是删除了该用户下的模式对象,是不会删除相应的表空间。
步骤二:删除表空间
DROP TABLESPACE tablespace_name包含内容和数据文件;