1、申明与赋值
1.程序块结构
declare-- 申明部分begin-- 执行部分 end;-- 写一个空的程序快declare-- 申明部分begin-- 执行部分 null;end;
2.最简单的程序
declare
-- 申明部分
begin
-- 执行部分
dbms_output.put_line('hello world');
end;
3.定义变量 变量赋值 变量是可变的
-- 已知长宽求周长
declare
-- 申明部分
v_long number;
v_wide number;
v_Perimeter number;
begin
-- 执行部分
v_long:= 5;
v_wide:= 3;
v_Perimeter:= (v_long + v_wide)*2;
dbms_output.put_line('v_Perimeter = '||v_Perimeter);
end;
-- 申明变量的时候可以直接赋值么 赋初始值
declare
-- 申明部分
v_long number:= 5;
v_wide number:= 3;
v_Perimeter number;
begin
-- 执行部分
v_Perimeter:= (v_long + v_wide)*2;
dbms_output.put_line('v_Perimeter = '||v_Perimeter);
end;
-- 变量是可变的
declare
-- 申明部分
v_long number:= 5;
v_wide number:= 3;
v_Perimeter number;
begin
-- 执行部分
v_long := 8;
dbms_output.put_line('v_long = '||v_long);
v_Perimeter:= (v_long + v_wide)*2;
dbms_output.put_line('v_Perimeter = '||v_Perimeter);
end;
4.定义常量 constant
-- 已知半径求面积
declare
-- 申明部分
v_pi constant number:= 3.14;
v_r number:= 3;
v_area number;
begin
-- 执行部分
v_area:= v_pi*v_r*v_r;
dbms_output.put_line('v_area = '||v_area);
end;
-- 特性 常量必须赋初始值 常量是不可变的
declare
-- 申明部分
v_pi constant number;
v_r number:= 3;
v_area number;
begin
-- 执行部分
v_pi:= 3.14;
v_area:= v_pi*v_r*v_r;
dbms_output.put_line('v_area = '||v_area);
end;
5.字符/日期数据类型的变量
declare
-- 申明部分
v_name varchar2(30):='张三';
v_date date:= sysdate;
begin
-- 执行部分
v_date:= to_date('20210101','yyyymmdd');
dbms_output.put_line('v_name = '||v_name);
dbms_output.put_line('v_date = '||v_date);
end;
6.隐式游标及其特性
-- 只能返回一行数据 返回多行或者没有数据都会报错
-- 语法 select into
declare
-- 申明部分
v_name varchar2(30);
v_sal number;
begin
-- 执行部分
select ename,sal into v_name,v_sal from emp where empno = 7499;
dbms_output.put_line('v_name = '||v_name);
dbms_output.put_line('v_sal = '||v_sal);
dbms_output.put_line(v_name||' 薪水是 '||v_sal);
end;
-- 特性1 返回多行数据会报错
declare
-- 申明部分
v_name varchar2(30);
v_sal number;
begin
-- 执行部分
select ename,sal into v_name,v_sal from emp ;
dbms_output.put_line(v_name||' 薪水是 '||v_sal);
end;
-- 特性2 没有数据会报错
declare
-- 申明部分
v_name varchar2(30);
v_sal number;
begin
-- 执行部分
select ename,sal into v_name,v_sal from emp where empno = 1;
dbms_output.put_line(v_name||' 薪水是 '||v_sal);
end;
-- 防报错 加聚合函数
declare
-- 申明部分
v_name varchar2(30);
v_sal number;
begin
-- 执行部分
select max(ename),max(sal) into v_name,v_sal from emp ;
dbms_output.put_line(v_name||' 薪水是 '||v_sal);
end;
7.%type / %rowtype 定义数据类型
-- %TYPE:引用数据库中的某列的数据类型或某个变量的数据类型。
declare
-- 申明部分
v_name emp.ename%type;
begin
-- 执行部分
select ename into v_name from emp where empno = 7499;
dbms_output.put_line(v_name);
end;
-- %ROWTYPE:引用数据库中的一行(所有字段)作为数据类型。
declare
-- 申明部分
v_all emp%rowtype;
begin
-- 执行部分
select ename,sal into v_all.ename,v_all.sal from emp where empno = 7499;
dbms_output.put_line(v_all.ename);
dbms_output.put_line(v_all.sal);
end;
2、IF判断
if
-- if判断
-- if 条件 then 结果 end if
-- 一个分支 如果 SMITH 的工资小于1000 输出努力
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 1000
then dbms_output.put_line('努力');
end if;
end;
-- 两个分支 如果 SMITH 的工资小于500 输出努力 否则输出很棒
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 500
then dbms_output.put_line('努力');
else dbms_output.put_line('很棒');
end if;
end;
-- 尽量少些 else
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 500
then dbms_output.put_line('努力');
elsif v_sal >= 500
then dbms_output.put_line('很棒');
end if;
end;
-- 多个分支 如果 SMITH 的工资小于500 输出努力 工资[500,2000) 输出可以 工资大于等于2000输出很棒
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 500
then dbms_output.put_line('努力');
elsif v_sal >= 500 and v_sal < 2000
then dbms_output.put_line('可以');
elsif v_sal >= 2000
then dbms_output.put_line('很棒');
end if;
end;
-- 换一种写法
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 500
then dbms_output.put_line('努力');
elsif v_sal >= 500 and v_sal < 2000
then dbms_output.put_line('可以');
else dbms_output.put_line('很棒');
end if;
end;
-- 比较难理解的写法
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
if v_sal < 500
then dbms_output.put_line('努力');
elsif v_sal < 2000
then dbms_output.put_line('可以');
elsif v_sal >= 2000
then dbms_output.put_line('很棒');
end if;
end;
case
-- 一个分支 如果 SMITH 的工资小于1000 输出努力
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 1000
then dbms_output.put_line('努力');
end case;
end;
-- 两个分支 如果 SMITH 的工资小于500 输出努力 否则输出很棒
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 500
then dbms_output.put_line('努力');
else dbms_output.put_line('很棒');
end case;
end;
-- 尽量少些 else
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 500
then dbms_output.put_line('努力');
when v_sal >= 500
then dbms_output.put_line('很棒');
end case;
end;
-- 多个分支 如果 SMITH 的工资小于500 输出努力 工资[500,2000) 输出可以 工资大于等于2000输出很棒
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 500
then dbms_output.put_line('努力');
when v_sal >= 500 and v_sal < 2000
then dbms_output.put_line('可以');
when v_sal >= 2000
then dbms_output.put_line('很棒');
end case;
end;
-- 换一种写法
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 500
then dbms_output.put_line('努力');
when v_sal >= 500 and v_sal < 2000
then dbms_output.put_line('可以');
else dbms_output.put_line('很棒');
end case;
end;
-- 比较难理解的写法
declare
v_sal number;
begin
select sal into v_sal from emp where ename = 'SMITH';
case when v_sal < 500
then dbms_output.put_line('努力');
when v_sal < 2000
then dbms_output.put_line('可以');
when v_sal >= 2000
then dbms_output.put_line('很棒');
end case;
end;
-- 建表造数
create table emp_1207 as select * from emp;
select * from emp_1207;
-- 条件后面 你想做什么事情就可以做什么事情
-- 把他的奖金改成 3000
declare
v_sal number;
begin
select sal into v_sal from emp_1207 where ename = 'SMITH';
if v_sal > 500
then update emp_1207 set comm = 3000 where ename = 'SMITH';
commit;
end if;
end;
-- 删除 30部门的数据
declare
v_sal number;
begin
select sal into v_sal from emp_1207 where ename = 'SMITH';
if v_sal > 500
then delete from emp_1207 where deptno = 30;
commit;
end if;
end;
3、FOR循环
-- 循环的语法 loop end loop
declare
begin
loop
end loop;
end;
-- 死循环 无条件循环
declare
begin
loop
null;
end loop;
end;
-- for 循环
-- 自然数求和 1..100 5050
declare
v_a number:= 0;
v_sum number:= 0;
begin
for i in 1..100 loop
v_a:= v_a + 1; -- 每循环一次加1
v_sum:= v_sum + v_a;
end loop;
dbms_output.put_line(v_sum);
end;
-- 看过程
declare
v_a number:= 0;
v_sum number:= 0;
begin
for i in 1..100 loop
v_a:= v_a + 1; -- 每循环一次加1
v_sum:= v_sum + v_a;
dbms_output.put_line(v_a||' '||v_sum); -- 循环100次这里就输出100次
end loop;
dbms_output.put_line(v_sum);
end;
-- 代码简化一下
declare
v_sum number:= 0;
begin
for i in 1..100 loop
v_sum:= v_sum + i;
dbms_output.put_line(i); -- 看i的变化
end loop;
dbms_output.put_line(v_sum);
end;
-- while 循环 基本上没有人这么写
declare
v_a number:= 0;
v_sum number:= 0;
begin
while v_a < 100 loop
v_a:= v_a + 1; -- 每循环一次加1
v_sum:= v_sum + v_a;
dbms_output.put_line(v_a);
end loop;
dbms_output.put_line(v_sum);
end;
-- 无条件循环 exit 退出条件在循环体里面
declare
v_a number:= 0;
v_sum number:= 0;
begin
loop
v_a:= v_a + 1; -- 每循环一次加1
v_sum:= v_sum + v_a;
-- exit when v_a = 100; -- 第一种退出方式
-- 第二种退出方式
if v_a = 100 then exit;
end if;
end loop;
dbms_output.put_line(v_sum);
end;
4、两数交换
declare
a number:= 10;
b number:= 5;
c number;
begin
c:= a; -- c=10 a=10
a:= b; -- c=10 a=5 b=5
b:= c; -- c=10 a=5 b=10
dbms_output.put_line('a='||a);
dbms_output.put_line('b='||b);
end;
-- 两表交换 建表造数
select * from emp_1207;
select * from emp_1207_bak;
select * from emp_1207_tmp;
create table emp_1207 as select * from emp;
create table emp_1207_bak as select * from emp_1207;
delete from emp_1207_bak where deptno = 20;
commit;
-- 交换表名
alter table emp_1207 rename to emp_1207_tmp;
alter table emp_1207_bak rename to emp_1207;
alter table emp_1207_tmp rename to emp_1207_bak;
5、求和 求奇偶
declare
v_sum_j number := 0;
v_sum_o number:= 0;
v_sum number := 0;
begin
for i in 1..100 loop
if mod(i,2) =1
then v_sum_j := v_sum_j + i;
elsif mod(i,2) =0
then v_sum_o := v_sum_o + i;
end if;
v_sum := v_sum + i;
end loop;
dbms_output.put_line('v_sum_j = '||v_sum_j);
dbms_output.put_line('v_sum_o = '||v_sum_o);
dbms_output.put_line('v_sum = '||v_sum);
end;
6、动态sql
-- 动态sql execute immediate
-- 建表造数
drop table emp_4;
create table emp_4 as select * from emp e;
select * from emp_4;
select * from emp_5;
-- ddl,truncate 不能直接用,要包装起来
declare
begin
-- execute immediate '';
-- truncate table emp_4;
-- execute immediate 'truncate table emp_4'; -- 工作中天天要用的
-- create table emp_5 as select e.* from emp_4 e where 1=2;
-- execute immediate 'create table emp_5 as select e.* from emp_4 e where 1=2';
-- alter table emp_5 add aaa number;
-- execute immediate 'alter table emp_5 add aaa number';
-- alter table emp_5 modify aaa varchar2(50);
-- execute immediate 'alter table emp_5 modify aaa varchar2(50)';
-- alter table emp_5 drop column aaa
-- execute immediate 'alter table emp_5 drop column aaa ';
-- alter table emp_5 rename column deptno to bbb;
-- execute immediate 'alter table emp_5 rename column deptno to bbb';
-- alter table emp_5 rename to emp_4;
-- execute immediate 'alter table emp_5 rename to emp_4';
-- drop table emp_4;
execute immediate 'drop table emp_4';
end;
7、存储过程
-- 存储过程 procedure sp
-- 建表造数
drop table emp_bak;
create table emp_bak as select * from emp where 1 = 2;
select * from emp_bak;
-- 最简单的程序过程
create procedure sp_emp_bak is
begin
insert into emp_bak
select * from emp where deptno = 10;
commit;
end;
-- 如果有就替换
create or replace procedure sp_emp_bak is
begin
insert into emp_bak
select * from emp where deptno = 10;
commit;
end;
-- 测试过程
-- 第一步 编译 执行这个sp的代码 仅仅是把这个代码存到我们的数据库
-- 第二步 调用
1.在对象这先找到要测试的sp>选择对应的sp右键>测试
2.sql窗口选择对应的sp右键>测试
3.直接sql窗口写调用语句
begin sp_emp_bak; end;