1. 程式人生 > >oracle-PLSQL的一些基本語句使用

oracle-PLSQL的一些基本語句使用

--PL/SQL例項
/*
declare
    宣告變數,初始化變數,宣告遊標
begin
    執行部分
exception
    異常捕獲部分
end;


*/
declare
    --宣告變數
    out_text varchar2(20);
    i integer;
begin
    out_text := '程式輸出222';
    i := 1/0;
    dbms_output.put_line(out_text);
    exception
        --出現異常之後執行
        when others then
            dbms_output.put_line('出現了一個異常');
end;


select * from emp;


--巢狀執行PL/SQL塊
declare
    out_text varchar2(20);
begin
    out_text := '外層PL/SQL塊';
    dbms_output.put_line(out_text);
    --巢狀
    declare
        inner_text varchar2(20) := '內層PL/SQL塊';
    begin
        dbms_output.put_line(inner_text);
    end;
end;


--常用的運算子
declare
    x number := 10;
    y number := 20;
    z number;
begin
    z := x*y;
    dbms_output.put_line('x*y='||z);
end;


declare
    ename varchar2(20) := 'tom';
begin
    ename := ename||'cat';
    dbms_output.put_line(ename);
end;


--通過select ... into 語句對變數進行賦值,使用該語句對變數進行賦值時,語句查詢結果不能是零行或多行(有且僅有一行)
declare
    v_ename varchar2(20);
begin
    select ename into v_ename from emp where empno=7943;
    dbms_output.put_line(v_ename);
end;


--%rowtype和%type的使用


--%rowtype:將資料庫表中的一行資料作為型別,在賦值時,需要查詢出對應列數的資料進行賦值
declare
    v_emp emp%rowtype;
begin
    select * into v_emp from emp where empno=7943;
    dbms_output.put_line('員工姓名:'||v_emp.ename||',職位:'||v_emp.job);
end;


--%type:將表中一列作為型別
declare
    v_ename emp.ename%type;
begin
    select ename into v_ename from emp where empno=7369;
    dbms_output.put_line(v_ename);
end;




--記錄型別
/*
type 型別名 is record(
type1 資料型別,
type2 資料型別,
...
);
*/
declare
    --定義型別
    type emp_type is record(
        empno emp.empno%type,
        ename emp.ename%type,
        sal emp.sal%type,
        job emp.job%type
    );
    --定義該型別的變數
    employee emp_type;
begin
    select empno,ename,sal,job into employee from emp where empno=7943;
    dbms_output.put_line(employee.empno||'  '||employee.ename||'  '||employee.sal||'  '||employee.job);
end;


/*
PL/SQL中的流程控制語句
    順序結構
    選擇結構
    迴圈結構
*/
--IF ... THEN  end if;
declare
    v_sal emp.sal%type;
begin
    select sal into v_sal from emp where empno=7934;
    --對薪資進行判斷,然後更新獎金列
    if v_sal>4000 then
        update emp set comm=100 where empno=7370;
    elsif v_sal <2000 then
        update emp set comm=500 where empno=7370;
    else 
        update emp set comm=200 where empno=7370;
    end if;
    commit;
end;


-- case when then 類似於java中的switch
declare
    v_grade varchar2(2);
begin
    v_grade := upper('&asd');
    case v_grade
        when 'A' then
            dbms_output.put_line('優');
        when 'B' THEN
            dbms_output.put_line('中');
        when 'C' THEN
            dbms_output.put_line('差');
        else 
            dbms_output.put_line('滾出去');
    end case;
end;


--PL/SQL迴圈結構
--loop ... end loop
-- 1+2+3....+100
declare 
    i number := 0;
    v_sum number := 0;
begin
    --無限迴圈
    loop 
        v_sum := v_sum + i;
        i := i + 1;
        --給無限迴圈指定出口
        if i>100 then
            exit;
        end if;
        dbms_output.put_line(i);
    end loop;
    dbms_output.put_line(v_sum);
end;


--while迴圈
declare
    i number := 0;
    v_sum number := 0;
begin
    while i<=100 loop
        v_sum := v_sum + i;
        i := i + 1;
    end loop;
    dbms_output.put_line(v_sum);
end;


--for
declare
    i number := 1;
    v_sum number := 0;
begin
    -- 1..100 會自動增長,預設情況是從小到大,如果需要從大到小需指定reverse屬性
    for i in reverse 1..100 loop
        v_sum := v_sum + i;
        dbms_output.put_line(i);
    end loop;
    dbms_output.put_line(v_sum);
end;


--動態sql
/*
execute immediate 動態sql字串 [into 變數名] [using 引數列表]
*/
declare
    v_ename varchar2(20) := 'tom';
    v_job varchar2(20) := 'dba';
    v_empno number := 7942;
begin
    --相當於jdbc  update emp set ename=:name 
    execute immediate 'update emp set ename=:1,job=:2 where empno=7943' using v_ename,v_job;
    
    execute immediate 'select ename from emp where empno=:1' into v_ename using v_empno;
    dbms_output.put_line(v_ename);
    commit;
end;


--遊標的使用
/*
使用遊標的步驟:1.定義  2.開啟  3.使用  4.關閉
*/
--靜態遊標
declare
    cursor my_cursor is select empno,ename from emp;
    --定義用於接收遊標資料的變數
    v_empno emp.empno%type;
    v_ename emp.ename%type;
begin
    --使用遊標的%isopen屬性判斷遊標是否開啟
    if not my_cursor%isopen then
        --使用open關鍵字開啟遊標
        open my_cursor;
    end if;
    --獲取到遊標中的第一行資料
    loop 
        fetch my_cursor into v_empno,v_ename;
        --資料取完之後需要退出迴圈
--        if my_cursor%notfound then
--            exit;
--        end if;
        exit when my_cursor%notfound;
        dbms_output.put_line(v_empno||'  '||v_ename);
    end loop;
    --關閉遊標
    close my_cursor;
end;


--oracle為了簡化遊標的使用提供了遊標的for迴圈
--隱式的打開了遊標,使用fetch獲取遊標中的資料,關閉了遊標
declare
    cursor my_cursor is select * from emp;
begin
    for employee in my_cursor loop
        dbms_output.put_line(employee.empno||' '||employee.ename||' '||employee.sal||' '||employee.deptno);
    end loop;
end;




--動態遊標的使用
/*
語法:type 遊標型別名 is ref cursor [return 返回值]
*/
declare
    --定義一個強遊標型別
    type my_cursor_type is ref cursor return emp%rowtype;
    --定義該遊標型別的遊標變數
    my_cursor my_cursor_type;
    --定義用於儲存遊標資料的變數
    v_emp emp%rowtype;
begin
    --開啟遊標
    open my_cursor for select * from emp;
    loop 
        fetch my_cursor into v_emp;
        exit when my_cursor%notfound;
        dbms_output.put_line(v_emp.empno||' '||v_emp.ename||' '||v_emp.sal);
    end loop;
end;