ORACLE PL/SQL基礎編程

--初次打開會話要運行的(不然就不能輸出數據)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

相關文章
相關標籤/搜索