Oracle数据库-3
来源:互联网 发布:泰勒公式矩阵形式 编辑:程序博客网 时间:2024/06/05 11:17
1、hello world
set serveroutput on
declare
--说明部分
begin
--程序
dbms_output.put_line('Hello World');
end;
/
2、引用型变量
--查询7839的姓名和薪水
set serveroutput on
declare
--定义变量保存姓名和薪水
--pename varchar2(20);
--psal number;
pename emp.ename%type;
psal emp.sal%type;
begin
--得到姓名和薪水
select ename,sal into pename,psal from emp where empno=7839;
dbms_output.put_line(pename||'的薪水是'||psal);
end;
/
3、记录型变量
--查询7839的姓名和薪水
set serveroutput on
declare
--定义记录型变量:代表一行
emp_rec emp%rowtype;
begin
select * into emp_rec from emp where empno=7839;
dbms_output.put_line(emp_rec.ename||'的薪水是'||emp_rec.sal);
end;
/
4、if语句
--判断用户从键盘输入的数字
set serveroutput on
--接收键盘输入
--num: 地址值,在该地址上 保存了输入的值
accept num prompt '请输入一个数字';
declare
--定义变量保存输入的数字
pnum number := #
begin
if pnum = 0 then dbms_output.put_line('您输入的是0');
elsif pnum = 1 then dbms_output.put_line('您输入的是1');
elsif pnum = 2 then dbms_output.put_line('您输入的是2');
else dbms_output.put_line('其他数字');
end if;
end;
/
5、循环
--打印1~10
set serveroutput on
declare
pnum number := 1;
begin
loop
--退出条件
exit when pnum > 10;
dbms_output.put_line(pnum);
--加一
pnum := pnum + 1;
end loop;
end;
/
6、涨工资
--涨工资,总裁1000 经理800 其他400
set serveroutput on
declare
--alter table "SCOTT"."EMP" rename column "JOB" to empjob
cursor cemp is select empno,empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
rollback;
open cemp;
loop
--取一条记录
fetch cemp into pempno,pjob;
exit when cemp%notfound;
--判断职位
if pjob = 'PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
elsif pjob = 'MANAGER' then update emp set sal=sal+800 where empno=pempno;
else update emp set sal=sal+400 where empno=pempno;
end if;
end loop;
close cemp;
--why? ---> ACID
commit;
dbms_output.put_line('完成');
end;
/
7、光标
--查询并打印员工的姓名和薪水
/*
1. 光标的属性:
%isopen %rowcount (影响的行数)
%found %notfound
2. 默认,一个会话中只能打开300个光标
SQL> show parameter cursor
NAME TYPE VALUE
------------------------------------ -------------------------------- -----------
cursor_sharing string FORCE
cursor_space_for_time boolean FALSE
open_cursors integer 300
session_cached_cursors integer 20
修改: alter system set open_cursors=400;
3. (思考):cursor_sharing 什么作用?---> 性能优化
EXACT(默认), FORCE, SIMILAR
*/
set serveroutput on
declare
--定义光标
cursor cemp is select ename,sal from emp;
pename emp.ename%type;
psal emp.sal%type;
begin
--打开光标
open cemp;
loop
--取一条记录
fetch cemp into pename,psal;
--退出条件
--exit when 没有取到记录;
exit when cemp%notfound;
dbms_output.put_line(pename||'的薪水是'||psal);
end loop;
--关闭光标
close cemp;
end;
/
8、带参数的光标
--查询某个部门的员工姓名
set serveroutput on
declare
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
begin
open cemp(20);
loop
fetch cemp into pename;
exit when cemp%notfound;
dbms_output.put_line(pename);
end loop;
close cemp;
end;
/
9、系统例外
--被0除
set serveroutput on
declare
pnum number;
begin
pnum := 1/0;
exception
when zero_divide then dbms_output.put_line('1:0不能做分母');
dbms_output.put_line('2:0不能做分母');
when value_error then dbms_output.put_line('算术或者转换错误');
when others then dbms_output.put_line('其他例外');
end;
/
10、自定义例外
--查询50号部门的员工姓名
set serveroutput on
declare
cursor cemp is select ename from emp where deptno=50;
pename emp.ename%type;
--自定义例外
no_emp_found exception;
begin
open cemp;
--取第一条记录
fetch cemp into pename;
if cemp%notfound then
--抛出例外
raise no_emp_found;
end if;
--pmon: process monitor
close cemp;
exception
when no_emp_found then dbms_output.put_line('没有找到员工');
when others then dbms_output.put_line('其他例外');
end;
/
11、实例1
/*
SQL语句:
select to_char(hiredate,'yyyy') from emp;
---> 集合 ---> 光标 ---> 循环 ---> 退出条件:notfound
变量:1. 初始值 2. 最终得到
每年入职的员工人数:
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on
declare
cursor cemp is select to_char(hiredate,'yyyy') from emp;
phiredate varchar2(4);
--每年入职的员工人数:
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
begin
open cemp;
loop
--取一个员工的入职年份
fetch cemp into phiredate;
--退出条件:notfound
exit when cemp%notfound;
--判断年份
if phiredate = '1980' then count80:=count80+1;
elsif phiredate = '1981' then count81:=count81+1;
elsif phiredate = '1982' then count82:=count82+1;
else count87:=count87+1;
end if;
end loop;
close cemp;
dbms_output.put_line('Total:'||(count80+count81+count82+count87));
dbms_output.put_line('1980:'||count80);
dbms_output.put_line('1981:'||count81);
dbms_output.put_line('1982:'||count82);
dbms_output.put_line('1987:'||count87);
end;
/
12、实例2
/*
SQL语句:
select empno,sal from emp order by sal;
---> 光标 ---> 退出:1. 总额 > 5w 2. notfound
变量:1. 初始值 2. 最终得到
涨工资的人数: countEmp number := 0;
涨后的工资总额: salTotal number;
1. select sum(sal) into salTotal from emp;
2. 涨后=涨前 + sal * 0.1
练习: 人数:7 总额:50205.325
*/
set serveroutput on
declare
cursor cemp is select empno,sal from emp order by sal;
pempno emp.empno%type;
psal emp.sal%type;
--涨工资的人数:
countEmp number := 0;
--涨后的工资总额:
salTotal number;
begin
--得到初始的工资总额
select sum(sal) into salTotal from emp;
open cemp;
loop
--1. 总额 > 5w
exit when salTotal > 50000;
--取一个员工
fetch cemp into pempno,psal;
--2. notfound
exit when cemp%notfound;
--涨工资
update emp set sal=sal*1.1 where empno=pempno;
--人数+1
countEmp := countEmp + 1;
--2. 涨后=涨前 + sal * 0.1
salTotal := salTotal + psal * 0.1;
end loop;
close cemp;
commit;
dbms_output.put_line('人数:'||countEmp||' 总额:'||salTotal);
end;
/
13、实例3
/*
SQL语句:
部门: select deptno from dept;
部门中员工的薪水:select sal from emp where deptno=???
变量:1. 初始值 2. 最终得到
每个段的人数:
count1 number; count2 number; count3 number;
部门的工资总额: salTotal number := 0;
1.select sum(sal) into salTotal from emp where deptno=???
2.累加
*/
set serveroutput on
declare
--部门
cursor cdept is select deptno from dept;
pdeptno dept.deptno%type;
--部门中员工的薪水
cursor cemp(dno number) is select sal from emp where deptno=dno;
psal emp.sal%type;
--每个段的人数:
count1 number; count2 number; count3 number;
--部门的工资总额:
salTotal number := 0;
begin
open cdept;
loop
--取一个部门
fetch cdept into pdeptno;
exit when cdept%notfound;
--初始化
count1:=0;count2:=0;count3:=0;
--部门的工资总额
select sum(sal) into salTotal from emp where deptno=pdeptno;
--取部门中员工的薪水
open cemp(pdeptno);
loop
--取一个员工
fetch cemp into psal;
exit when cemp%notfound;
--判断
if psal < 3000 then count1:=count1+1;
elsif psal>=3000 and psal<6000 then count2:=count2+1;
else count3:=count3+1;
end if;
end loop;
close cemp;
--保存结果
insert into msg values(pdeptno,count1,count2,count3,nvl(saltotal,0));
end loop;
close cdept;
commit;
dbms_output.put_line('完成');
end;
/
14、第一个存储过程
--打印Hello World
/*
调用存储过程:
1. exec sayHelloWorld();
2. begin
sayHelloWorld();
sayHelloWorld();
end;
/
*/
create or replace procedure sayHelloWorld
as
--说明部分
begin
dbms_output.put_line('Hello World');
end;
/
15、带参数的存储过程
--给指定的员工涨100,并且打印涨前和涨后的薪水
create or replace procedure raisesalary(eno in number)
as
--定义变量保存涨前的薪水
psal emp.sal%type;
begin
--得到涨前的薪水
select sal into psal from emp where empno=eno;
--涨100
update emp set sal=sal+100 where empno=eno;
--要不要commit?
dbms_output.put_line('涨前:'||psal||' 涨后:'||(psal+100));
end;
/
16、存储函数
--查询某个员工的年收入
create or replace function queryempincome(eno in number)
return number
as
--定义变量保存月薪和奖金
psal emp.sal%type;
pcomm emp.comm%type;
begin
select sal,comm into psal,pcomm from emp where empno=eno;
--返回年收入
return psal*12+nvl(pcomm,0);
end;
/
17、out参数
--查询某个员工的姓名 月薪 职位
/*
思考:
1. 查询某个员工的所有信息 ---> out参数太多
2. 查询某个部门中的所有员工信息 ---> 返回集合
*/
create or replace procedure queryempinfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
end;
/
18、JDBCUtils.java
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtils {
private static String driver = "oracle.jdbc.OracleDriver";
private static String url = "jdbc:oracle:thin:@192.168.56.101:1521:orcl";
private static String user = "scott";
private static String password = "tiger";
static{
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
//DriverManager.registerDriver(driver)
}
public static Connection getConnection(){
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/*
* 运行Java程序
* java -Xms100M -Xmx200M HelloWorld
*
* 技术方向:
* 1. 性能调优 ---> tomcat
* 2. 故障诊断 ---> 死锁
*/
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs = null;// ----> java GC
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
st = null;
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn = null;
}
}
}
}
19、在out参数中使用光标
2. 查询某个部门中的所有员工信息 ---> 返回集合
包头
CREATE OR REPLACE PACKAGE MYPAKCAGE AS
type empcursor is ref cursor;
procedure queryEmpList(dno in number, empList out empcursor);
END MYPAKCAGE;
包体
CREATE OR REPLACE PACKAGE BODY MYPAKCAGE AS
procedure queryEmpList(dno in number, empList out empcursor) AS
BEGIN
open empList for select * from emp where deptno=dno;
END queryEmpList;
END MYPAKCAGE;
20、TestOracle
package demo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import org.junit.Test;
public class TestOracle {
/*
* create or replace procedure queryempinfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
*/
@Test
public void testProcedure(){
//{call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{call queryempinfo(?,?,?,?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于in参数,赋值
call.setInt(1, 7839);
//对于out参数,申明
call.registerOutParameter(2, OracleTypes.VARCHAR);
call.registerOutParameter(3, OracleTypes.NUMBER);
call.registerOutParameter(4, OracleTypes.VARCHAR);
//执行
call.execute();
//取出结果
String name = call.getString(2);
double sal = call.getDouble(3);
String job = call.getString(4);
System.out.println(name+"\t"+sal+"\t"+job);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
/*
* create or replace function queryempincome(eno in number)
return number
*/
@Test
public void testFunction(){
//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
String sql = "{?=call queryempincome(?)}";
Connection conn = null;
CallableStatement call = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//第一个是out参数
call.registerOutParameter(1, OracleTypes.NUMBER);
//第二个是in参数
call.setInt(2, 7839);
call.execute();
//取出年收入
double income = call.getDouble(1);
System.out.println(income);
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, null);
}
}
@Test
public void testCursor(){
String sql = "{call MYPAKCAGE.queryEmpList(?,?)}";
Connection conn = null;
CallableStatement call = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
call = conn.prepareCall(sql);
//对于in参数,赋值
call.setInt(1, 20);
//对于out参数 申明
call.registerOutParameter(2, OracleTypes.CURSOR);
call.execute();
//取出结果
rs = ((OracleCallableStatement)call).getCursor(2);
while(rs.next()){
//取出一个员工
String name = rs.getString("ename");
double sal = rs.getDouble("sal");
System.out.println(name+"\t"+sal);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JDBCUtils.release(conn, call, rs);
}
}
}
21、第一个触发器
--每当成功插入新员工后,自动打印"成功插入新员工"
create trigger abcd
after insert
on emp
declare
begin
dbms_output.put_line('成功插入新员工');
end;
/
22、触发器应用
/*
触发器应用一:实施复杂的安全性检查
禁止在非工作时间插入新员工
周末:to_char(sysdate,'day') in ('星期六','星期日')
上班前 下班后:to_number(to_char(sysdate,'hh24')) not between 9 and 17
*/
create or replace trigger securityemp
before insert
on emp
begin
if to_char(sysdate,'day') in ('星期六','星期日','星期三') or
to_number(to_char(sysdate,'hh24')) not between 9 and 17 then
--禁止insert
raise_application_error(-20001,'禁止在非工作时间插入新员工');
end if;
end;
/
23、触发器应用
/*
触发器应用二: 数据的确认
涨后的工资不能少于涨前的工资
*/
create or replace trigger checksalary
before update
on emp
for each row
begin
--if 涨后的薪水 < 涨前的薪水 then
if :new.sal < :old.sal then
raise_application_error(-20002,'涨后的工资不能少于涨前的工资。涨前:'||:old.sal||' 涨后:'||:new.sal);
end if;
end;
/
阅读全文
0 0
- Oracle 数据库笔记3
- Oracle(3)数据库
- oracle数据库安装3
- Oracle数据库-3
- oracle数据库3
- Oracle数据库-3
- oracle数据库《3》
- oracle 数据库 练习题 3
- Oracle Start Up 3:Oracle数据库基础
- Oracle数据库(关系型数据库3)
- ORACLE 数据库开发经验总结3
- oracle 数据库
- Oracle数据库
- Oracle数据库
- Oracle数据库
- oracle数据库
- Oracle数据库
- oracle数据库
- Red and Black (广搜 队列)
- Lintcode57 3Sum solution 题解
- ACM中关于浮点型的精确度问题
- Ubuntu下切换JDK1.6 到Open JDK7 java 和javac 版本
- 数字图像处理实验(16):PROJECT 06-03,Color Image Enhancement by Histogram Processing
- Oracle数据库-3
- tensorflow框架基础之Tensor
- 周测3 T1 无碳小车
- Lintcode58 4Sum solution 题解
- 细粒度的审计+删除细粒度审计
- FL2440——RT3070 softAP模式 实现无线路由器功能
- Eclipse手动集成ADT和SDK
- POJ 1518 Problem Bee 笔记
- L1-002. 打印沙漏