--初次打開會話要運行的(不然就不能輸出數據)html
SET SERVEROUTPUT ONsql
--變量賦值(賦值符號default、:=) / 表明執行數據庫
DECLARE ide
sname VARCHAR(10) := '張三';oop
BEGINfetch
dbms_output.put_line(sname);code
END;server
/htm
------------------------對象
--聲明常量
DECLARE
pi CONSTANT NUMBER := 3.14;
r NUMBER DEFAULT 3;
area NUMBER;
BEGIN
area := pi*r*r;
dbms_output.put_line(area);
END;
/
------------------------
--宿主常量
VAR emp_name VARCHAR(30);
BEGIN
SELECT ename INTO :emp_name FROM emp WHERE empno=7499;
end;
/
print emp emp_name;
------------------------
--屬性數據類型
--%rowtype 表示引入數據庫中的一行做爲數據類型(實體對象)
--%type 表示引用某個變量或者數據庫的列的類型做爲變量的數據類型(引用類型)
--%ROWTYPE(實體)
DECLARE
mydept dept%ROWTYPE;
BEGIN
SELECT * INTO mydept FROM dept WHERE deptno=10;
dbms_output.put_line(mydept.dname||'----'||mydept.loc);
END;
/
-------------------
--%TYPE(引用類)
DECLARE
e_job emp.job%TYPE;
my_job varchar2(10);
your_job my_job%TYPE;
BEGIN
SELECT job INTO e_job FROM emp WHERE empno=7934;
my_job := e_job;
your_job := e_job;
dbms_output.put_line('emp:'||e_job||' '||'my:my_'||my_job||' '||'your:yout_'||your_job);
END;
-------------------
--PL/SQL條件控制和循環控制
--if then
DECLARE
newSal emp.sal%TYPE;
BEGIN
SELECT sal INTO newSal FROM emp WHERE empno=7369;
IF newSal<1500 THEN
UPDATE emp SET comm=1000 WHERE empno=7369;
END IF;
COMMIT;
END;
-------------------
--if then elsif
DECLARE
newSal emp.sal%TYPE;
BEGIN
SELECT sal INTO newSal FROM emp WHERE empno=7369;
IF newSal>1500 THEN
UPDATE emp SET comm=1000 WHERE empno=7369;
ELSIF newSal<1500 THEN
UPDATE emp SET comm=500 WHERE empno=7369;
ELSE
UPDATE emp SET comm=400 WHERE empno=7369;
END IF;
COMMIT;
END;
-------------------
--case
DECLARE
v_grade CHAR(1):=UPPER('&p_grade');
BEGIN
CASE
WHEN v_grade='A' THEN
dbms_output.put_line('Excellent');
WHEN v_grade='B' THEN
dbms_output.put_line('Very Good');
WHEN v_grade='C' THEN
dbms_output.put_line('Good');
ELSE
dbms_output.put_line('No such grade');
END CASE;
END;
--case[selector]
DECLARE
v_grade CHAR(1):=UPPER('&p_grade');
BEGIN
CASE v_grade
WHEN 'A' THEN
dbms_output.put_line('Excellent');
WHEN 'B' THEN
dbms_output.put_line('Very Good');
WHEN 'C' THEN
dbms_output.put_line('Good');
ELSE
dbms_output.put_line('No such grade');
END CASE;
END;
-------------------
DECLARE
v_grade CHAR(1):=UPPER('&p_grade'); --&:輸入
p_grade varchar2(10);
BEGIN
p_grade :=
CASE v_grade
WHEN 'A' THEN
'Excellent'
WHEN 'B' THEN
'Very Good'
WHEN 'C' THEN
'Good'
ELSE
'No such grade'
END;
dbms_output.put_line('Grade:'||v_grade||',the result is'||p_grade);
END;
-------------------------------
--decode
DECLARE
v_grade CHAR(1) := UPPER('&p_grade');
p_grade VARCHAR2(20);
BEGIN
SELECT DECODE(v_grade,'A','Excellent','B','Very Good','C','Good','No such grade') INTO p_grade
FROM dual;
dbms_output.put_line(p_grade);
END;
-------------------------------
--循環結構
DECLARE
pnum NUMBER := 1;
BEGIN
WHILE pnum < 10 LOOP
dbms_output.put(pnum);
pnum := pnum + 1;
END LOOP;
END;
--------------
DECLARE
pnum NUMBER DEFAULT 1;
BEGIN
LOOP
EXIT WHEN pnum > 10;
dbms_output.put_line(pnum);
pnum := pnum + 1;
END LOOP;
END;
-------------
--範圍循環
DECLARE
BEGIN
FOR pnum IN 1..5 LOOP
dbms_output.put_line(pnum);
END LOOP;
END;
---------------
--遊標loop
DECLARE
--定義一個實體類用於打印相關字段
temp_emp emp%ROWTYPE;
--相似於Java中的ResultSet
CURSOR mycursor IS SELECT * FROM emp WHERE sal>1600;
BEGIN
--打開遊標
OPEN mycursor;
--遍歷ResultSet
LOOP
FETCH mycursor INTO temp_emp;
EXIT WHEN mycursor%NOTFOUND;
dbms_output.put_line(temp_emp.empno||'----'||temp_emp.ename);
END LOOP;
END;
----------------
--異常(exception)
--(1)系統例外no_data_found
DECLARE
pname emp.ename%TYPE;
BEGIN
SELECT ename INTO pname FROM emp WHERE empno=1234;
EXCEPTION
WHEN no_data_found THEN dbms_output.put_line('沒有找到該員工');
WHEN OTHERS THEN dbms_output.put_line('其餘意外');
END;
-------------------------
--(2)系統例外too_many_rows
DECLARE
pname emp.ename%TYPE;
BEGIN
SELECT ename INTO pname FROM emp WHERE deptno=10;
EXCEPTION
WHEN too_many_rows THEN dbms_output.put_line('匹配了多行');
WHEN OTHERS THEN dbms_output.put_line('其餘例外');
END;
-------------------------
--(3)系統例外zero_divide
DECLARE
pnum NUMBER;
BEGIN
pnum := 1/0;
EXCEPTION
WHEN zero_divide THEN dbms_output.put_line('0不能作除數');
WHEN OTHERS THEN dbms_output.put_line('其餘例外');
END;
------------------------
--(4)系統例外value_error 算數或類型轉換錯誤
DECLARE
pnum NUMBER;
BEGIN
pnum := 'asd';
EXCEPTION
WHEN value_error THEN dbms_output.put_line('算數或轉換錯誤');
WHEN OTHERS THEN dbms_output.put_line('其餘例外');
END;
------------------------
--(5)自定義例外 能夠當成一個變量 可拋出
DECLARE
CURSOR cemp IS SELECT ename FROM emp WHERE deptno=500;
pname emp.ename%TYPE;
no_emp_found EXCEPTION;
BEGIN
OPEN cemp;
FETCH cemp INTO pname;
IF cemp%NOTFOUND THEN
RAISE no_emp_found;
END IF;
CLOSE cemp;--(不用擔憂沒有關閉光標,系統會啓動一個進程pmon(progress monitor來關閉它)
EXCEPTION
WHEN no_emp_found THEN dbms_output.put_line('沒有找到該部門的員工');
WHEN OTHERS THEN dbms_output.put_line('其餘例外');
END;
---------------------------------------
--建立存儲過程例子:
CREATE OR REPLACE PROCEDURE proc1(
p_para1 VARCHAR2,
p_para2 OUT VARCHAR2,
p_para3 IN OUT VARCHAR2
)AS
v_name VARCHAR2(20);
BEGIN
v_name := '張三';
p_para3 := v_name;
dbms_output.put_line('p_para3:'||p_para3);
END;
-----------------------
--簡單存儲過程例子
CREATE OR REPLACE PROCEDURE findEmpJob(myempno IN NUMBER,myename OUT varchar2,myjob OUT varchar2)
AS
BEGIN
SELECT ename,job INTO myename,myjob FROM emp WHERE empno=myempno;
END;
-----------------------
--在初次打開PL/SQL時要運行如下這行代碼
set serveroutput on
--返回結果集
--建立一個存儲過程包
CREATE OR REPLACE PACKAGE mypack
IS
TYPE mycursor IS REF CURSOR;
END mypack;
--建立存儲過程方法
CREATE OR REPLACE PROCEDURE findEmpJob(
myempno IN NUMBER,
myename OUT varchar2,
myjob OUT VARCHAR2,
other_name OUT mypack.mycursor
)
AS
BEGIN
SELECT ename,job INTO myename,myjob FROM emp WHERE empno=myempno;
OPEN other_name FOR
SELECT ename,job FROM emp WHERE empno IN(
SELECT empno FROM emp
MINUS
SELECT empno FROM emp WHERE empno=myempno
);
END;
SELECT * FROM emp;
SELECT * FROM dept;
-----------------------------------------
--執行動態SQL
--execute immediate
DECLARE
sql_stmt varchar2(200);
table_name VARCHAR2(20);
BEGIN
table_name:= 'stu_201704';
sql_stmt:= 'create table '||table_name ||'(';
sql_stmt:= sql_stmt ||'id int primary key,';
sql_stmt:= sql_stmt ||'stu_name varchar2(20)';
sql_stmt:= sql_stmt ||')';
dbms_output.put_line(sql_stmt);
EXECUTE IMMEDIATE sql_stmt;
END;
--需求
/*
1.查詢部門
2.遍歷部門結果
a.生成動態create table sql
b.統計對應此部門的收入(工資+獎金)
3.執行動態create sql
4.執行動態insert
5.commit
*/
-- 動態SQL——查詢,建表,統計,插入
declare
--定義遊標,遍歷全部部門
cursor mydept_cur is select * from dept where deptno in (select deptno from emp);
--定義部門實體類
mydept dept%rowtype;
--建立表的sql,須要動態執行
create_str varchar2(100);
--插入表的sql,須要動態執行
insert_str varchar2(200);
--定義查詢平均收入
query_avg_income_str varchar2(100);
income_str varchar2(50);
begin
create_str:= 'create table dept_income(';
insert_str:= 'insert into dept_income values (';
query_avg_income_str:= 'select avg(sal)+avg(nvl(comm,0)) from emp where deptno=:1';
--打開遊標
open mydept_cur;
loop
-- while (rs.next()) {
--}
--模仿rs.next(),作2件事
fetch mydept_cur into mydept;
exit when mydept_cur%notfound;
-- 追加中間的字段以及類型
create_str:= create_str || mydept.dname||' number,';
execute immediate query_avg_income_str into income_str using mydept.deptno;
insert_str:= insert_str|| income_str||',';
end loop;
--關閉遊標
close mydept_cur;
create_str:= create_str||'dt varchar2(200))';
insert_str:= insert_str|| '''201703'')' ; --中間那對引號是表示轉義字符
--輸出語句
--dbms_output.put_line(create_str);
--dbms_output.put_line(insert_str);
--動態執行語句
execute immediate create_str;
execute immediate insert_str;
--DML語句須要提交
commit;
end;
-----------------------------
--動態PL/SQL捕獲異常例子:
declare
--定義遊標,遍歷全部部門
cursor mydept_cur is select * from dept where deptno in (select deptno from emp);
--定義部門實體類
mydept dept%rowtype;
--建立表的sql,須要動態執行
create_str varchar2(100);
--插入表的sql,須要動態執行
insert_str varchar2(200);
--定義查詢平均收入
query_avg_income_str varchar2(100);
income_str varchar2(50);
begin
create_str:= 'create table dept_income(';
insert_str:= 'insert into dept_income values (';
query_avg_income_str:= 'select avg(sal)+avg(nvl(comm,0)) from emp where deptno=:1';
--打開遊標
open mydept_cur;
loop
-- while (rs.next()) {
--}
--模仿rs.next(),作2件事
fetch mydept_cur into mydept;
exit when mydept_cur%notfound;
-- 追加中間的字段以及類型
create_str:= create_str || mydept.dname||' date,';
execute immediate query_avg_income_str into income_str using mydept.deptno;
insert_str:= insert_str|| income_str||',';
end loop;
--關閉遊標
close mydept_cur;
create_str:= create_str||'dt varchar2(200))';
insert_str:= insert_str|| '''201703'')' ; --中間那對引號是表示轉義字符
--輸出語句
--dbms_output.put_line(create_str);
--dbms_output.put_line(insert_str);
--動態執行語句
execute immediate create_str;
execute immediate insert_str;
--DML語句須要提交
commit;
--異常捕獲
exception
--when 異常名字 then
when others then
dbms_output.put_line('捕獲到其它異常:'||SQLCODE||' '||SQLERRM);
end;
這裏是有關PL/SQL的基礎代碼:
謝謝各位博友的支持!
如需轉載請註明出處:http://www.cnblogs.com/ZRJ-boke/p/6600623.html