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指導!