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;