pl/sql

本文详细介绍了SQL中的过程化语句,如类型定义、判断、循环和游标,以及PL/SQL中的变量管理、赋值、函数使用和键盘输入操作。涵盖了变量声明、比较、循环结构、DML操作和异常处理等内容,适合深入理解SQL编程技巧。

在sql语句基础增加了一些过程化的语句

过程化的语句:类型定义 判断 循环 游标...
匿名块:
有名块:
匿名块的语法:
[declare] 声明的部分
声明的内容
begin 执行的部分
      要执行的语句;
      [exception]--异常
      要执行的语句;
end;
注:每个部分语句后面都要加分号';'end后面也要加';'多写注释
    赋值使用符号 :=  判断相等的是 =
--声明的部分
声明变量的语法:变量名 类型长度
                 v_a
类型长度:
数值型      number int
字符型      char varchar/varchar2
日期型      date timestamp
布尔型      boolean 值返回对或者错 不能打印 用来判断
表.列%type  和某张表的某个列类型长度一致
表%rowtype  和某张表的表结构一致

%type的特性:
1.所引用的数据库列的类型可以不知道
2.所引用的数据库列的类型可以实时改变

注:变量必须是要v开头  变量的名字不要和列名 关键字等重名
    一个变量一个时刻只能接受一个值
打印:
dbms_output.put_line(值) 换行打印
dbms_output.put(值) 不换行打印 (必须和换行打印配合使用)
变量的赋值
1.直接赋值
declare
v_a number:=123;--声明时直接赋值
v_b number;
begin
  v_b:=999;--在执行时赋值
  dbms_output.put(v_a);--不换行
  dbms_output.put_line(v_b);--换行打印,结尾必须换行才能出结果
end;--输出看结果123999
再来一个都换行的
declare
v_a number:=123;--声明时直接赋值
v_b number;
begin
  v_b:=999;--在执行时赋值
  dbms_output.put_line(v_a);--换行
  dbms_output.put_line(v_b);--换行
end;--输出看结果123
--              999
结尾必须执行换行打印才能出结果!!!
2.变量的值赋给变量
declare
v_a number:=123;
v_b number;
begin
  v_b:=v_a;
  dbms_output.put_line(v_a);
  dbms_output.put_line(v_b);
end;
3.变量可以多次赋值 新值会覆盖旧值
declare
v_a date:=date'2022-1-1';
begin
  dbms_output.put_line(v_a);
  v_a:=sysdate;--赋新值
  dbms_output.put_line(v_a);
end;
4.变量的赋值可以计算
declare
v_1 number:=2;
v_2 number:=3;
v_3 number;
begin
  v_3:=power(v_1,v_2);--2的3次方
  dbms_output.put_line(v_3);
end;
5.变量的赋值可以使用函数
declare
v_1 varchar(20):='i like apple';
v_2 varchar(20):=upper(v_1);
v_3 varchar(20):=initcap(v_1);
begin
  dbms_output.put_line(v_1);
  dbms_output.put_line(v_2);
  dbms_output.put_line(v_3);
end;
--v_y 当前时间的年 v_m 当前时间的月 v_d 是日 打印v_y的v_m次方再开v_d次方
declare
v_y number(20):=to_char(sysdate,'yyyy');
v_m number(20):=to_char(sysdate,'mm');
v_d number(20):=to_char(sysdate,'dd');
v_t number;
begin
  v_t:=power(power(v_y,v_m),1/v_d);
  dbms_output.put_line(v_t);
end;
6.键盘直接赋值
--键盘输入生日 查询自己活了多少年多少月多少天
declare
v_date date:=date'&生日';--&宏代换,需要键盘输入值
v_s    date:=sysdate;
v_y    varchar(50);
begin
  dbms_output.put_line('输入你的生日是:'||v_date);
  select floor(months_between(v_s,v_date)/12)||'年'||
         floor(mod(months_between(v_s,v_date),12))||'月'||
         floor(v_s-add_months(v_date,
               floor(months_between(v_s,v_date))))||'天'
         into v_y from dual;
  dbms_output.put_line('你的年龄是:'||v_y);
end;
7.select into 赋值
select into 可以多列 但是只能单行
--打印SMITH的工资和职位
declare
v_s number;
v_j varchar(20);
begin
  select sal,job into v_s,v_j
  from emp
  where ename='SMITH';
  dbms_output.put_line('SMITH的工资是:'||v_s||' 职位是:'||v_j);
end;
--键盘输入一个年份 输出这个年份是平年还是闰年
declare
v_nf number(20):='&年份';
v_n varchar(5);
begin
  dbms_output.put_line('输入你的年份是:'||v_nf);
  select case when to_char(to_date
        (v_nf||'-12-31','yyyy-mm-dd'),'ddd') =366 then '闰年'
        else '平年' end into v_n from dual;
  dbms_output.put_line('你的年份是:'||v_n);
end;
--打印emp中King的员工信息(姓名,工资,职位)
declare
v_s number;
v_j varchar(20);
begin
  select sal,job into v_s,v_j
  from emp
  where ename='KING';
  dbms_output.put_line('KING的姓名是:KING 工资是'||v_s||' 职位是:'||v_j);
end;
第二种方法
declare
v_e emp%rowtype;--在表里打印格式相同
begin
  select * into v_e from emp where ename='KING';
  dbms_output.put_line('名字:'||v_e.ename||' 工资:'||v_e.sal||' 工作:'||v_e.job);
end;
--打印dept中10部门的部门名称和部门所在地
declare
v_mc varchar(20);
v_szd varchar(20);
begin
  select dname,loc into v_mc,v_szd
  from dept
  where deptno=10;
  dbms_output.put_line('10部门的名称是:'||v_mc||' 所在地是:'||v_szd);
end;
第二种方法
declare
v_D dept.dname%type;--表里打印不用看类型
v_L dept.loc%type;
begin
  select dname,loc into v_D,v_L from dept where deptno=10;
  dbms_output.put_line('10部门名称:'||v_D||' 所在地:'||v_L);
end;
8. returning into --把DML的值赋值给变量
只能单行 可以多列
创建一个emp_1数据同emp一致 先删表重建 drop table emp_1;
create table emp_1 as select * from emp;
--删除smith的行 打印删除的姓名和工资
--插入一条数据 打印插入的姓名和工资
--更新KING 的名字小写 工资+10000 打印更新的工资和姓名
declare
v_n emp.ename%type;
v_s emp.sal%type;
begin
  delete from emp_1 where ename='SMITH'
  returning ename,sal into v_n,v_s;
  dbms_output.put_line('删除了'||v_n||' '||v_s);
  ----------------删除-----------------
  insert into emp_1(ename,sal) values('aimo',2333)
  returning ename,sal into v_n,v_s;
  dbms_output.put_line('插入了'||v_n||' '||v_s);
  ----------------插入-----------------
  update emp_1 set ename=lower(ename),sal=sal+10000
               where ename='KING'
  returning ename,sal into v_n,v_s;
  dbms_output.put_line('更新了'||v_n||' '||v_s);
  ----------------更新-----------------
end;
select * from emp;
emp表被删除 重新插入
insert into emp values(7369,'SMITH','CLERK',7902,date'1980-12-17',800,0.00,20);
注:变量的声明:宁缺毋滥
--判断和循环
判断:case when 判断
      if 判断
if 判断语法:
if 条件1 then 执行的语句;
  elsif 条件2 then 执行的语句;
  ....
  [else 执行的语句;]
end if;
--键盘输入一个数字 大于0打印正数 小于0打印负数 0打印零
declare
v_n number(20):='&数字';
begin
  dbms_output.put_line('你输入的数字是:'||v_n);--这行可省略
  if v_n>0 then dbms_output.put_line('正数');
  elsif v_n<0 then dbms_output.put_line('负数');
        else dbms_output.put_line('零');
  end if;
end;
/*键盘输入一个员工编号 如果工资大于3000打印有钱人
                               大于2000显示一般般
                               大于1000打印还凑合
                               小于1000打印好可怜*/
declare
v_e emp.empno%type:=&员工编号;
v_s emp.sal%type;
begin
  select sal into v_s from emp where empno=v_e;--员工编号在emp表
  dbms_output.put_line('你输入的员工编号是:'||v_e);
  if v_s>3000 then
    dbms_output.put_line('有钱人');
  elsif v_s>2000 then
    dbms_output.put_line('一般般');
  elsif v_s>1000 then
    dbms_output.put_line('还凑合');
  else dbms_output.put_line('好可怜');
  end if;
end;
--case when判断语法
语法:
case when 条件1 then 要执行的语句;
     when 条件2 then 要执行的语句;
     ...
     else 要执行的语句;
end case;
--键盘输入一个字符 如果是大写打印大写字母 小写打印小写字母 否则打印不认识
declare
v_z varchar(20):='&字符';
begin
  case when v_z between 'A' and 'Z' then
       dbms_output.put_line('大写字母');
       when v_z between 'a' and 'z' then
       dbms_output.put_line('小写字母');
       else dbms_output.put_line('不认识');
   end case;
end;
sql中 case when 和pl/sql 中的 case when 有何不同:
1.sql中 case when可以加列  plsql中只能加条件
2.sql中 case when不加分号  plsql中then后执行的语句要加分号
3.sql中 case when以end结束 plsql中end case结束 
4.sql中 case when不能加DML  plsql中可以加DML
循环 loop
 普通循环
 while循环
 for循环--重点

--普通循环--无条件的循环
语法:(都在begin后执行)
loop
  执行的语句;
  exit when 退出的条件;
  [执行的语句;]
end loop;
注:设置一个自增变量 防止出现死循环
--循环打印1-10
declare
v_a number(20):=1;
begin
  loop
    dbms_output.put(v_a||' ');
    exit when v_a=10;
    v_a:=v_a+1;
  end loop;
  dbms_output.put_line(' ');
end;
--循环打印1...10的和  55
declare
v_1 number(20):=1;
v_2 number(20):=0;
begin
  loop
    v_2:=v_2+v_1;
    v_1:=v_1+1;
    exit when v_1>10;
  end loop;
  dbms_output.put_line(v_2);
end;
--打印1+2+3+4+5+6+7+8+9+10=55这个式子
declare
v_1 number(20):=1;
v_2 number(20):=0;
begin
  loop
    dbms_output.put(v_1||'+');
    v_2:=v_2+v_1;
    v_1:=v_1+1;
    exit when v_1>=10;
  end loop;
  dbms_output.put_line(v_1||'='||(v_2+v_1)); 
end;
--while 循环
语法:
while 进入循环的条件
  loop
    执行的语句
    [exit when 退出的条件;]
  end loop;
--循环打印1到10  while
declare
v_a number(20):=1;
begin
  while v_a<10
    loop
      dbms_output.put(v_a||' ');
      v_a:=v_a+1;
  end loop;
  dbms_output.put_line(v_a);
end;
--循环打印1...10的和  55   whlile
declare
v_1 number(20):=1;
v_2 number(20):=0;
begin
  while v_1<=10
  loop
    v_2:=v_2+v_1;
    v_1:=v_1+1;
  end loop;
  dbms_output.put_line(v_2);
end;
--打印1+2+3+4+5+6+7+8+9+10=55这个式子   while
declare
v_1 number(20):=1;
v_2 number(20):=0;
begin
  while v_1<10
  loop
    dbms_output.put(v_1||'+');
    v_2:=v_2+v_1;
    v_1:=v_1+1;
  end loop;
  dbms_output.put_line(v_1||'='||(v_2+v_1)); 
end;
--for 循环
语法:
for 变量 in [ reverse ]小值..大值
  loop
    要执行的语句;
    [exit when 条件;]--中途退出的条件
  end loop;
--循环打印1到10
begin
  for i in 1..10
    loop
      dbms_output.put(i||' ');
    end loop;
    dbms_output.put_line(' ');
end;
--打印1+2+3+4+5+6+7+8+9+10=55这个式子   for
declare
v_i number(20):=0;
begin
  for i in 1..9
    loop
      dbms_output.put(i||'+');
      end loop;
  dbms_output.put_line('10=55'); 
end;
--或--
declare
v_i number(20):=0;
begin
  for i in 1..9
    loop
      v_i:=v_i+i;
      dbms_output.put(i||'+');
      end loop;
  dbms_output.put_line(10||'='||(v_i+10)); 
end;
--键盘输入一个值 计算这个值的阶乘 n!=n×(n-1)×(n-2)..×1
declare
v_1 number:=1;
begin
  for i in reverse 1..&n --往回翻
    loop
      v_1:=v_1*i;
    end loop;
    dbms_output.put_line(v_1);
end;
--打印直角三角形
*
* *
* * *
* * * *
* * * * *
begin
  for i in 1..5   --打印层数
    loop
      for a in 1..i  --打印*的数量
      loop
        dbms_output.put('* ');--每一层的* 不换行
      end loop;
        dbms_output.put_line('');--换行
    end loop;
end;
--打印99乘法表
begin
  for a in 1..9
    loop
      for b in reverse 1..a
        loop
        dbms_output.put(rpad(a||'*'||b||'='||a*b,8,' '));
        end loop;
     dbms_output.put_line('');--换行
     end loop;
end;

-- 顺序控制
GOTO语句
语法:
  <<标签>>
  代码
  IF 条件 then
    xxx;
    goto 标签;
  end if;  
  
DECLARE
  V NUMBER := 1;  -- 初始化条件
BEGIN
  <<bi90>>
  DBMS_OUTPUT.PUT_LINE(V); -- 循环体  2 3 
  V := V + 1;  -- 迭代条件  3 4
  IF V <= 10 THEN   -- 循环条件
    GOTO bi90;
  END IF;
END;

循环的四大条件:
  初始化条件
  循环体
  迭代条件
  循环条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值