PL/SQL块中只能直接嵌入SELECT,DML(INSERT,UPDATE,DELETE)
以及事务控制语句(COMMIT,ROLLBACK,SAVEPOINT),
而不能直接嵌入DDL语句(CREATE,ALTER,DROP)和DCL语句(GRANT,REVOKE)
1.检索单行数据
1.1使用标量变量接受数据
- v_ename emp.ename%type;
- v_sal emp.sal%type;
- select ename,sal into v_ename,v_sal from emp where empno=&no;
1.2使用记录变量接受数据
- type emp_record_type is record(
- ename emp.ename%type,sal emp.sal%type);
- emp_record emp_record_type;
- select ename,sal into emp_record from emp where empno=&no;
1.3嵌入SELECT语句注意事项:
使用SELECT INTO语句时,必须要返回一条数据,并且只能返回一条数据
no_date_found:
select into没有返回数据
too_many_rows:
select into返回多条数据
where子句使用注意事项:
使用的变量名不能与列名相同,否则触发TOO_MANY_ROWS例外.
2.操纵数据
2.1使用VALUES子句插入数据
- v_deptno dept.deptno%type;
- v_dname dept.dname%type;
- v_deptno:=no;
- v_dname:='&name';
- insert into dept (deptno,dname) values(v_deptno,v_dname);
2.2使用子查询插入数据
- v_deptno emp.deptno%type:=&no;
- insert into employee select * from emp where deptno=v_deptno;
2.3更新数据
使用表达式更新列值
- v_deptno dept.deptno%type:=no;
- v_loc dept.loc%type:='&loc';
- update dept set loc=v_loc where deptno=v_deptno;
2.4使用子查询更新列值
- v_ename emp.ename%type:='&name';
- update emp set (sal,comm) = (select sal,comm from emp where ename=v_ename) where job = (select job from emp where ename=v_ename) ;
2.5删除数据
使用变量删除数据
- v_deptno dept.deptno%type:=&no;
- delete from dept where deptno=v_deptno;
2.6使用子查询删除数据
- v_ename emp.ename%type:='&name';
- delete from emp where deptno=(select deptno from emp where ename=v_ename);
3.SQL游标
游标是指向上下文区的指针,包括隐含游标(SQL游标)和显式游标两种类型
SQL游标用于处理SELECT INTO ,INSERT,UPDATE以及DELETE语句.
显式游标用于处理多行的SELECT语句
SQL游标包括:SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT,SQL%ISOPEN等四种属性
3.1 SQL%ISOPEN:执行时,会隐含的打开和关闭游标.因此该属性的值永远都是FALSE
3.2 SQL%FOUND:用于确定SQL语句执行是否成功.当SQL有作用行时,为TRUE,否则为FALSE
- v_deptno emp.deptno%type:=&no;
- update emp set salsal=sal*1.1 where deptno=v_deptno;
- if sql%found
- then dbms_output.put_line('执行成功');
- else
- dbms_output.putline('失败');
- endif
3.3 sql%notfound:确定SQL语句执行是否成功,当SQL有作用行时,为false,否则为true
3.4 sql%rowcount:返回SQL语句所作用的总计行数
- v_deptno emp.deptno%type:=&no;
- update emp set salsal=sal*1.1 where deptno=v_deptno;
- dbms_output.put_line('修改了'||sql%rowcount||'行');
4.事务控制语句(TCL)
事务控制语句包括COMMIT,ROLLBACK以及SAVEPOINT等三种语句
- v_sal emp.sal%type:=&salary;
- v_ename emp.ename%type:='&name';
- update emp set sal=v_sal where ename=v_ename;
- commit;
- exception
- when others then
- rollback;
- insert into temp values(1);
- savepoint a1;
- insert into temp values(2);
- savepoint a2;
- insert into temp values(3);
- savepoint a3;
- rollback to a2;
- commit;
5.控制结构
条件分支语句
5.1简单条件判断
- v_sal number(6,2);
- select sal into v_sal from emp where
- lower(ename)=lowe('&&name');
- if v_sal<2000 then update emp set
- sal=v_sal+200 where lower(ename)=lower('&name')
- end if;
5.2二重条件分支
- v_comm number(6,2);
- select comm into v_comm from emp where empno=&&no;
- if v_comm<>0 then update emp set comm=v_comm+100 where empno=&no;
- else update emp set comm=200 where empno=&no;
- end if
5.3多重条件分支
- v_job varchar2(10);
- v_sal number(6,2);
- select job,sal into v_job,v_sal from emp where empno=&&no;
- if v_job='president' then
- update emp set sal=v_sal+1000 where empno=&no;
- else if v_job='manager' then
- update emp setsal=v_sal+500 where empno=&no;
- else
- update emp set sal=v_sal+200 where empno=&no;
- end if;
5.4 CASE语句:
在CASE语句中使用单一选择符进行等值比较
- declare
- v_deptno emp deptno%type;
- begin
- v_deptno:=&no;
- case v_deptno
- when 10 then update emp set comm=100 where deptno=v_deptno;
- when 20 then update emp set comm=80 where deptno=v_deptno;
- when 30 then update emp set comm=50 where deptno=v_deptno;
- else
- dbms_output.put_line("不存在');
- end case;
- end;
5.5 在CASE语句中使用多种条件比较
- declare
- v_sal emp.sal%type;
- v_ename emp.ename%type;
- begin
- select ename,sal into v_ename,v_sal from emp where empno=&no;
- case
- when v_sal<1000 then update emp set comm=100 where ename=v_ename;
- when v_sal<2000 then update emp set comm=80 where ename=v_ename;
- when v_sal<6000 tehn update emp set comm=50 where ename=v_ename;
- end case;
- end;
5.6循环语句
有基本循环,WHILE循环,FOR循环
基本循环:一定要包含EXIT语句,定义循环控制变量
- create table temp(cola int);
- eclare
- i int:=1;
- begin
- loop
- insert into temp values(i);
- exit when i=10;
- ii:=i+1;
- end loop;
- end;
5.7 WHILE循环:定义循环控制变量,并在循环体内改变循环控制变量的值
- declare
- i int:=1;
- begin
- while i<=10 loop
- insert into temp values(i);
- ii:=i+1;
- end loop;
- end;
5.8 for循环:使用FOR循环时,ORACLE会隐含定义循环控制变量.
- for counter in[reverse]
- lower_bound..upper_bound loop
- statement1;
- statement2;
- .......
- end loop;
5.9 counter是循环控制变量,并且该变量由ORACLE隐含定义,不需要显示定义;
lower_bound和upper_bound分别对应循环控制变量的上下界值.默认情况下,
FOR循环,每次会自动增一,指定REVERSE选项时,每次循环控制变量会减一
- begin
- for i in reverse 1..10 loop
- insert into temp values(i);
- end loop;
- end;
5.10嵌套循环和标号:通过在嵌套循环中使用标号,可以区分内层循环和外层循环
,并且可以在内层循环中直接退出外层循环
- declare
- result int;
- begin
- <<outer>>
- for i in 1..100 loop
- <<inter>>
- for j in 1..100 loop
- result:=i*j;
- exit outer when result=1000;
- exit when result=500;
- end loop inner;
- dbms_ouput.put_line(result);
- end loop outer;
- dbms_output.put_line(result);
- end;
6.顺序控制语句
PL/SQL不仅提供了条件分支语句和循环控制语句,而且还提供了顺序控制语句GOTO
和NULL.一般情况下不使用
6.1 GOTO:用于跳转到特定标号处去执行语句.
- GOTO LABEL_NAME;
- declare
- i int :=1;
- begin
- loop
- insert into temp values(i);
- if i=10 then
- goto end_loop
- end if;
- ii:=i+1;
- end loop;
- <<end_loop>>
- dbms_output.put_line('循环结束');
- end;
6.2 null:不会执行任何操作,并且会直接将控制传递到下一条语句.
- declare
- v_sal emp.sal%type;
- v_ename emp.ename%type;
- begin
- select ename,sal into v_ename,v_sal from
- emp where empno=&no;
- if v_sal<3000 then update emp set
- comm=sal*0.1 where ename=v_ename;
- else
- null;
- end if;
- end;
感谢April-MyHou指导!