PL/SQL 知识 (个人笔记)(二)

PL/SQL 知识 (个人笔记)(二)

个人笔记
接上篇
PL/SQL 知识 (个人笔记)(一)

**

9.动态SQL:

**
定义:SQL语句不是固定不变的,每执行一次都会变化.主要用于执行DDL.

execute immediate: 执行动态SQL

(1). 在代码块中执行DDL语句时,需要将语句赋到变量,注意需要用单引号包裹,然后execute immediate 变量名;

declare
v_sql varchar2(300);
begin
v_sql:='alter table emp modify ENAME not null';
execute immediate v_sql;
end;

(2). 若执行的代码中包含单引号时,可以使用q’[]'包裹语句赋到变量,也可以将代码中的单引号改为双引号:

declare
v_empno emp.empno%type;
v_empno1 emp.empno%type;
v_sql varchar2(300);
begin
v_sql2:='select empno  from emp where ename=''SMITH'''; 
v_sql3:=q'[select empno from emp where ename='ALLEN']';
execute immediate v_sql2 into v_empno;
execute immediate v_sql3 into v_empno1;
dbms_output.put_line(v_empno);
dbms_output.put_line(v_empno1);
end;

(3). 使用excute immediate执行语句有输出时,须用 execute immediate 变量 into 变量名方式,将变量值赋给到变量中,方可打印:

declare
v_empno emp.empno%type;
v_sql varchar2(300);
begin
v_sql3:=q'[select empno from emp where ename='ALLEN']';
execute immediate v_sql into v_empno;
dbms_output.put_line(v_empno);
end;

(4).使用execute immediate执行SQL,并需要从键盘获取输入时,格式如下:
若条件为字符串,则须用单引号包裹:

declare
v_empno emp.empno%type;
v_sql varchar2(300);
begin
v_sql:=q'[select empno from emp where ename='&员工姓名']';
execute immediate v_sql into v_empno;
dbms_output.put_line(v_empno);
end;

(5). execute immediate绑定变量:
即sql语句中不直接使用值,而是使用变量,执行时再输入值,即为绑定变量的方式,对于大量数据时,绑定变量效率高;

declare
v_empno emp.empno%type;
v_sql varchar2(300);
begin
v_sql4:=q'[select empno  from emp where ename=:1]';
execute immediate v_sql into v_empno using 'SMITH';
dbms_output.put_line(v_empno);
end;

代码:

declare
v_empno emp.empno%type;
v_sql  varchar2(300);
v_sql1 varchar2(300);
v_sql2 varchar2(300);
v_sql3 varchar2(300);
v_sql4 varchar2(300);
v_sql5 varchar2(300);
begin
v_sql:='alter table emp modify ENAME not null';
--dbms_output.put_line(v_sql);
--execute immediate v_sql;
v_sql1:=q'[create index IDX_EMP_MGR on emp(mgr)]';
--execute immediate v_sql1; 
--create index IDX_EMP_MGR on emp(mgr);
v_sql2:='select empno  from emp where ename=''SMITH'''; 
v_sql3:=q'[select empno from emp where ename='ALLEN']';
v_sql4:=q'[select empno  from emp where ename=:1]';
--v_sql5:=q'[select empno from emp where ename='&员工姓名']';
--execute immediate v_sql5  into v_empno;
execute immediate v_sql4  into v_empno using 'SMITH';
dbms_output.put_line(v_empno);
end;

重点:
1.动态SQL的执行 execute immediate方式;
2.动态SQL需要用单引号或者q’[]'包裹;
3.动态SQL主要用于执行DDL语句,比如我们之前讲的分区交换;
4.动态SQL可以执行DML语句,比如select语句,但执行方式与之前有差异,需要用 execute immediate SQL语句 into 变量名 方式将数据打印出来;
5.学会使用绑定变量,单参数的,多参数的.0

练习:

--1.使用动态SQL和%type的方式,查出emp表中ename是‘JONES’的人的JOB;
declare
v_job emp.job%type;
v_sql varchar2(300);
begin
v_sql:= q'[select job from emp where ename='JONES']';
execute immediate v_sql into v_job; 
dbms_output.put_line('JOB是: '||v_job);
end;
--2.使用%rowtype的方式定义变量,查出dept表的第一行数据,要求打印出所有的列;
declare
v_dept dept%rowtype;
begin
select * into v_dept from dept where rownum<2;
dbms_output.put_line('DEPTNO: '||v_dept.DEPTNO||', DNAME: '||v_dept.DNAME||', LOC:'||v_dept.LOC);
end;
--3.使用动态SQL方式新建一张EMP_0212的表,包含empno, ename和job三列;
declare
v_sql varchar2(500);
begin
v_sql:= q'[create table EMP_0212
(
       empno number(4),
       ename varchar2(30),
       job   varchar2(30)
)]';
execute immediate v_sql;
end;
--4.设计一个计算器,从键盘输入两个值,得出其和;
declare
v_num1 number(38) :=&数值1;
v_num2 number(38) :=&数值2;
v_sum  number(38);
begin
v_sum:= v_num1+v_num2;
dbms_output.put_line('两个数的和是: '||v_sum);
end;
--5.使用绑定变量方式,编写动态SQL,输出EMP表中JOB是PRESIDENT的人的名字;
declare
v_name emp.ename%type;
v_sql varchar2(300);
begin
v_sql:=q'[select ename from emp where job=:1]';
execute immediate v_sql into v_name using 'PRESIDENT';
dbms_output.put_line('JOB为PRESIDENT的人是: '||v_name);
end;

**

10.流程控制

**
if-else

if 表达式 then 执行动作;
else 执行动作;
end if;
if 表达式 then 执行动作;
elsif 表达式 then 执行动作;
elsif 表达式 then 执行动作;
else 执行动作;
end if;

范例:

declare
v_a number(3) :=10;
begin
if v_a<10 then
  dbms_output.put_line('v_a小于10');
  elsif v_a=10 then
    dbms_output.put_line('v_a等于10');
    else
        dbms_output.put_line('v_a等于10');
        end if; 
end;

注意事项:
(1). 有if就有end if,成对出现;
(2). else可以没有;
(3). eslif的写法要注意;
(4).每一句结束都有分号;

case-when:
–等值判断:
case 列名/表达式
when 值 then 执行动作;
when 值 then 执行动作;
when 值 then 执行动作
else 执行动作;
end case;

范例:

declare
v_c number(3) :=10;
begin
  case v_c
    when 1 then
      dbms_output.put_line('v_c是'||v_c);
      when 10 then
        dbms_output.put_line('v_c是'||v_c);
          else
            dbms_output.put_line('v_c是'||v_c);
            end case;
end;

–范围判断:
case
when 表达式 then 执行动作;
when 表达式 then 执行动作;
when 表达式 then 执行动作;
else 执行动作;
end case;

范例:

declare
v_b number(3) :=10;
begin
  case 
    when v_b<5 then 
    dbms_output.put_line('v_b小于5');
    when v_b>=5 and v_b<10 then
      dbms_output.put_line('v_b在5到10之间');
      when v_b>=10 and v_b<15 then 
        dbms_output.put_line('v_b在10到15之间');
        else
          dbms_output.put_line('v_b大于15');
          end case;
end;

注意事项:
(1).有case就有end case,成对出现;
(2).when的个数,根据实际情况控制;
(3).每局结束都要有分号;

练习:

create table emp_0213 as select * from emp;

1.查询emp_0213表,如果sal<=1000,则sal增加500,如果sal>1000且sal<=1500,则sal增加550,如果sal>1500且sal<3000,sal增加600,其余的sal变为原来的1.2倍;
2.查询emp_0213表,如果deptno是10,则sal增加500, deptno是20,则sal增加600,其余的sal增加700;
3.键盘输入性别,输入M则返回 男, F则返回性别女 其他情况返回 Others;

declare
v_sex varchar2(20) :=&请输入M或者F;
begin
      if  v_sex='M' then
        dbms_output.put_line('男');
        elsif v_sex='F' then
          dbms_output.put_line('女');
          else
            dbms_output.put_line('Others');
            end if;
end;
declare
v_sex varchar2(20) :='&请输入M或者F';
begin
      if  v_sex='M' then
        dbms_output.put_line('男');
        elsif v_sex='F' then
          dbms_output.put_line('女');
          else
            dbms_output.put_line('Others');
            end if;
end;

4.键盘输入成绩,90或以上为优秀,70(包含70)-90为良好,60(包含60)-70为及格,其余情况为不及格;

declare
v_score number(3) :=&请输入一个成绩;
begin
  if v_score>=90 then
    dbms_output.put_line('成绩优秀');
    elsif v_score>=70 and v_score<90 then
      dbms_output.put_line('成绩良好');
      elsif v_score>=60 and v_score<70 then
        dbms_output.put_line('成绩及格');
        else
          dbms_output.put_line('不及格');
          end if;
end;

case-when:

declare
v_score number(3) :=&请输入一个成绩;
begin
  case
    when v_score>=90 then
      dbms_output.put_line('成绩优秀');
      when v_score>=70 and v_score<90 then
        dbms_output.put_line('成绩良好');
        when v_score>=60 and v_score<70 then
          dbms_output.put_line('成绩及格');
          else
            dbms_output.put_line('不及格');
            end case;
end;

猜你喜欢

转载自blog.csdn.net/yang_z_1/article/details/111878723