--示例1  PL/SQL 的基本语法
                declare  --声明:变量、游标
  v_num number(5) :=5;  --变量名 [constant:常量] 数据类型  [赋值] 
begin    --程序开始
  DBMS_OUTPUT.PUT_LINE('v_num的当前值为:'|| v_num);
--  if v_num>=10  then 
--    null;    --什么都不执行,只是为了填充语法;
--  else 
--    v_num :=v_num+10;
--  end if;
  
  
  if v_num<10 then
      v_num :=v_num+10;
  end if;
  DBMS_OUTPUT.PUT_LINE('v_num的更新值为:'|| v_num);
--exception    --异常
end;  --结束
              
--示例2  输出李浩鑫的地址
                declare
  --查询结果必须 =1 否则无法存储,报错
  v_address VARCHAR2(20);  --用来存储查询出来的地址
  v_name VARCHAR2(20) :='李浩鑫';
begin
  select "Address" into v_address
  from "Student"
  where "StudentName"=v_name;
  DBMS_OUTPUT.PUT_LINE(v_name||'的地址是:'||v_address);
exception
  when others then
  DBMS_OUTPUT.PUT_LINE('没有查到相关信息');
end;
              
--示例3  查询学号为8的学生姓名,并输出
                declare
  v_name "Student"."StudentName"%type;  --引用表中字段的类型,作为变量数据类型
  v_no number(20) :=8;
begin
  select "StudentName" into v_name
  from "Student"
  where "StudentNo"=v_no;
  DBMS_OUTPUT.PUT_LINE(v_no||'的姓名是:'||v_name);
exception
when others then
  DBMS_OUTPUT.PUT_LINE('没有查到相关信息');
end;
              
--示例4  查询学号为8的学生姓名和电话,并输出
                declare
  v_stuInfo "Student"%ROWTYPE; --引用表中所有字段的类型作为变量(集合)的类型
  v_no number(20) :=8;
begin
  select * into v_stuInfo
  from "Student"
  where "StudentNo"=v_no;
  DBMS_OUTPUT.PUT_LINE(v_no||'的姓名是:'||v_stuInfo."StudentName");
  DBMS_OUTPUT.PUT_LINE(v_no||'的电话是:'||v_stuInfo."Phone");
exception
when others then
  DBMS_OUTPUT.PUT_LINE('没有查到相关信息');
end;
              
--示例5  条件判断1:根据小明的成绩获得奖励
                declare
  v_score number(10) :=85;
begin
  if v_score>80 then
    DBMS_OUTPUT.PUT_LINE('奖励一个鸡腿');
  elsif v_score>60 then    --注意:elsif !!
    DBMS_OUTPUT.PUT_LINE('什么都不奖励');
  else
    DBMS_OUTPUT.PUT_LINE('奖励男女混合双打');
  end if;
exception
  DBMS_OUTPUT.PUT_LINE('没有查到相关信息');
end;
              
--小练习:>90的-10,>60且<=90加10,<=60加20分
declare
  v_score "Result"."StudentResult"%TYPE;
  v_stuNo "Result"."StudentNo"%TYPE :=1;
  v_subNo "Result"."SubjectNo"%TYPE :=2;
begin
  --查询出指定学生的指定科目的成绩,并存入变量
                  select "StudentResult" into v_score 
  from "Result"
  where "StudentNo"=v_stuNo and "SubjectNo"=v_subNo;
  --根据规则,修改变量赋值
  if v_score >90 then
    v_score :=v_score-10; --修改变量值
  elsif v_score >=60 then
    v_score :=v_score+10;  --修改变量值
  else
    v_score :=v_score+20; --修改变量值
  end if;
  --将修改后的变量值写入数据表中
  update "Result" set "StudentResult"=v_score
  where "StudentNo"=v_stuNo and "SubjectNo"=v_subNo;
--exception
END;
              
--示例6    等值判断  case 类似于Java中switch结构
                DECLARE
  v_count number(10);  --表示学生表中的总人数
BEGIN
  select count(1) into v_count
  from "Student";
  
  CASE v_count
  WHEN 6 THEN
    DBMS_OUTPUT.PUT_LINE('一共有'||v_count||'个人');
  WHEN 7 THEN
    DBMS_OUTPUT.PUT_LINE('一共有'||v_count||'个人');
  ELSE
    DBMS_OUTPUT.PUT_LINE('一共有好多个人');
  END CASE;
END;
              
--示例7    等值判断  case
                DECLARE
  v_count number(10);  --表示学生表中的总人数
BEGIN
  select count(1) into v_count
  from "Student";
  
  CASE   --如果when后是条件判断,那么case后不加变量
  WHEN v_count<=3 THEN
    DBMS_OUTPUT.PUT_LINE('一共有好少个人');
  WHEN v_count>=4 and v_count<=8 THEN
    DBMS_OUTPUT.PUT_LINE('一共有4-8个人');
  ELSE
    DBMS_OUTPUT.PUT_LINE('一共有好多个人');
  END CASE;
END;
              
--示例8   循环  loop:默认是一个无限循环,需要exit人工(强制)退出
                DECLARE
  v_num number(10) :=1;
BEGIN
  LOOP  --循环开始
    v_num :=v_num+2;  --循环操作
    DBMS_OUTPUT.PUT_LINE(v_num);--循环操作
  IF v_num>=20 THEN    --根据需求
    EXIT;  --退出Loop循环
  END IF; 
END LOOP;  --退出循环结构
END;
--示例9   while循环
DECLARE
  v_num number(10) :=1;
BEGIN
  while v_num<=20 loop
--    v_num :=v_num+2;  --循环操作
    DBMS_OUTPUT.PUT_LINE(v_num);--循环操作
  end loop;
END;
              
--示例10  for循环
                DECLARE
  v_num number(10) :=1;
BEGIN
  for i in 1..20 loop
    DBMS_OUTPUT.PUT_LINE(v_num);--循环操作
    v_num :=v_num +2;
  IF v_num>=20 THEN    --根据需求
    EXIT;  --退出Loop循环
  END IF; 
  end loop;
END;
              
--示例11  异常:exception
                DECLARE
  v_count number;  --默认长度255
  v_excep exception;
  v_excep2 exception;
BEGIN
  select count(1) into v_count
  from "Student" where "StudentNo"=1;
  if v_count>1 then
    raise v_excep; --raise:抛出  抛出一个异常对象
  elsif v_count=1 then
    DBMS_OUTPUT.PUT_LINE('找到了学号为1的学生');
  elsif v_count=0 then
    raise v_excep2;
  end if;
EXCEPTION  --处理异常
  when v_excep then  --匹配异常
    DBMS_OUTPUT.PUT_LINE('捕获到异常,学号有重复');
  when v_excep2 then
    DBMS_OUTPUT.PUT_LINE('不存在此学生');
  when others then  --捕获异常
    DBMS_OUTPUT.PUT_LINE('其他异常');
END;
              
--示例12  动态SQL,向表中插入一条数据
                DECLARE
  v_no number(4) :=7;  --参数变量
  v_name VARCHAR2(20) := 'Oracle';  --参数变量
  v_hour number(4) := 40;  --参数变量
  v_gradeId number(4) :=3;  --参数变量
  
  v_sql_str  VARCHAR2(255);  --存储sql语句变量
BEGIN
  --编写SQL语句,并设置占位符“:1”
  v_sql_str :='INSERT into "Subject" values(:1,:2,:3,:4) ';
  --用参数填充占位符
  --execute:执行  immediate:立即  using:使用
  execute immediate v_sql_str using v_no,v_name,v_hour,v_gradeId;
  commit;  --提交
END;
              
--示例13  游标,类似于Java中的迭代器
                DECLARE
  v_name "Student"."StudentName"%TYPE;
  v_phone "Student"."Phone"%TYPE;
  v_Address "Student"."Address"%TYPE;
--声明游标  cursor:光标
cursor c_stu is 
  select "StudentName","Phone","Address"  
  from "Student" where "StudentNo"=2;
BEGIN
  --打开游标
  open c_stu;
  --提取游标中的信息,并存入变量
  fetch c_stu into v_name,v_phone,v_Address;
  --输出信息
  DBMS_OUTPUT.PUT_LINE('姓名:'||v_name);
  DBMS_OUTPUT.PUT_LINE('电话:'||v_phone);
  DBMS_OUTPUT.PUT_LINE('地址:'||v_Address);
  
  --关闭游标
  close c_stu;
END;
              
--示例14   使用游标遍历多条结果
                DECLARE
  v_name "Student"."StudentName"%TYPE;
  v_phone "Student"."Phone"%TYPE;
  v_Address "Student"."Address"%TYPE;
  
  cursor c_stu is
  select "StudentName","Phone","Address" from "Student";
BEGIN
  --使用for循环遍历多条数据时,不需要打开游标,不需要提取,不需要关
  for stu in c_stu loop
    v_name :=stu."StudentName";
    v_phone :=stu."Phone";
    v_Address :=stu."Address";
    DBMS_OUTPUT.PUT_LINE('姓名:'||v_name);
    DBMS_OUTPUT.PUT_LINE('电话:'||v_phone);
    DBMS_OUTPUT.PUT_LINE('地址:'||v_Address);
  end loop;
END;