oracle PL/SQL示例
Pl/sql 簡單示例
查詢單列
如果我想使用PL/SQL得到下面sql查詢的結果 SQL> conn scott/tiger Connected. SQL> select ename from emp where empno=7839;
ENAME ---------- KING
SQL> PL/SQL SQL> declare 2 vename varchar2(15); 3 begin 4 select ename into vename from emp where empno=7839; 5 dbms_output.put_line(vename); 6 end; 7 /
PL/SQL procedure successfully completed.
SQL> 需要開啟serveroutput SQL>save /tmp/p1 Created file /tmp/p1.sql SQL> set serveroutput on SQL> start /tmp/p1.sql KING
PL/SQL procedure successfully completed.
SQL>
嘗試使用指令碼引數 [oracle@yang ~]$ vi /tmp/p1.sql
set serveroutput on declare vename varchar2(15); vempno number:=&1; begin select ename into vename from emp where empno=vempno; dbms_output.put_line(vename); end; / SQL> start /tmp/p1.sql Enter value for 1: 7839 (這裡輸出想要查詢的empno的值) old 3: vempno number:=&1; new 3: vempno number:=7839; KING
PL/SQL procedure successfully completed.
SQL> 可以隱藏顯示的新舊值 SQL> set verify off SQL> start /tmp/p1.sql Enter value for 1: 7839 KING
PL/SQL procedure successfully completed.
SQL> 還可以直接執行指令碼後加引數
SQL> start /tmp/p1.sql 7839 KING
PL/SQL procedure successfully completed.
SQL>
使用動態SQL實現 SQL> declare 2 vename varchar2(15); 3 begin 4 execute immediate 'select ename from emp where empno=7839' into vename; 5 dbms_output.put_line(vename); 6 end; 7 / KING
PL/SQL procedure successfully completed.
SQL> 或者 [oracle@yang ~]$ vi /tmp/q2.sql
declare vename varchar2(15); begin execute immediate 'select ename from emp where empno=:1' into vename using 7839; dbms_output.put_line(vename); end; / 當然也可以使用指令碼引數 [oracle@yang ~]$ vi /tmp/q2.sql
declare vename varchar2(15); vempno number:=&1; begin execute immediate 'select ename from emp where empno=:1' into vename using vempno; dbms_output.put_line(vename); end; /
|
查詢多列
SQL> select ename,sal from emp where empno=7839;
ENAME SAL ---------- ---------- KING 5000
SQL> 修改指令碼 [oracle@yang ~]$ vi /tmp/p1.sql
set serveroutput on declare vename varchar2(15); vsal number; vempno number:=&1; begin select ename,sal into vename,vsal from emp where empno=vempno; dbms_output.put_line(vename||' '||vsal); end; / 執行指令碼 SQL> start /tmp/p1.sql 7839 KING 5000
PL/SQL procedure successfully completed.
SQL> 修改動態sql指令碼 [oracle@yang ~]$ vi /tmp/q2.sql
declare vename varchar2(15); vempno number:=&1; vsal number; begin execute immediate 'select ename,sal from emp where empno=:1' into vename,vsal using vempno; dbms_output.put_line(vename||’ ‘||vsal); end; /
執行指令碼 SQL> start /tmp/q2.sql 7839 KING 5000
PL/SQL procedure successfully completed.
SQL>
|
使用複合變數呼叫
SQL> declare 2 type r1 is record(vename varchar2(20),vsal number); 3 v_r r1; 4 begin 5 select ename,sal into v_r from emp where empno=&1; 6 dbms_output.put_line(v_r.vename||' '||v_r.vsal); 7 end; 8 /
KING 5000
PL/SQL procedure successfully completed.
SQL> SQL> save /tmp/q3 Created file /tmp/q3.sql SQL> start /tmp/q3.sql 7839 KING 5000
PL/SQL procedure successfully completed.
SQL>
|
定義自動匹配資料型別
[oracle@yang ~]$ vi /tmp/p1.sql
set serveroutput on declare vename emp.ename%type; vsal emp.sal%type; vempno number:=&1; begin select ename,sal into vename,vsal from emp where empno=vempno; dbms_output.put_line(vename||' '||vsal); end; / SQL> start /tmp/p1.sql 7839 KING 5000
PL/SQL procedure successfully completed.
SQL> |
使用rowtype變數
[oracle@yang ~]$ vi /tmp/p4.sql
set serveroutput on declare vemp emp%rowtype; vempno number:=&1; begin select * into vemp from emp where empno=vempno; dbms_output.put_line(vemp.ename||' '||vemp.sal); end; / SQL> start /tmp/p4.sql 7839 KING 5000
PL/SQL procedure successfully completed.
SQL> |
對於輸出多條記錄可以使用遊標或迴圈語句
SQL> select ename,sal from emp where deptno=10;
ENAME SAL ---------- ---------- CLARK 2450 KING 5000 MILLER 1300
SQL> 使用for迴圈 [oracle@yang ~]$ vi /tmp/p5.sql
begin for i in (select ename,sal from emp where deptno=10) loop dbms_output.put_line(i.ename||' '||i.sal); --修改為(rpad(i.ename,15,’ ‘)||' '||i.sal)可以使輸出的欄位對齊) end loop; end; / SQL> start /tmp/p5.sql CLARK 2450 KING 5000 MILLER 1300
PL/SQL procedure successfully completed.
SQL> |
對於判斷的語句PL/SQL實現
SQL> select ename,sal,decode(deptno,10,sal*1.1,20,sal*1.2,30,sal*1.3,sal) from emp;
ENAME SAL DECODE(DEPTNO,10,SAL*1.1,20,SAL*1.2,30,SAL*1.3,SAL) ---------- ---------- --------------------------------------------------- SMITH 800 960 ALLEN 1600 2080 WARD 1250 1625 JONES 2975 3570 MARTIN 1250 1625 BLAKE 2850 3705 CLARK 2450 2695 SCOTT 3000 3600 KING 5000 5500 TURNER 1500 1950 ADAMS 1100 1320
ENAME SAL DECODE(DEPTNO,10,SAL*1.1,20,SAL*1.2,30,SAL*1.3,SAL) ---------- ---------- --------------------------------------------------- JAMES 950 1235 FORD 3000 3600 MILLER 1300 1430
14 rows selected.
SQL>
[oracle@yang ~]$ vi /tmp/p6.sql
declare vdeptno number; begin vdeptno:=&1; if vdeptno=10 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal*1.1); end loop; elsif vdeptno=20 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal*1.2); end loop; elsif vdeptno=30 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal*1.3); end loop; else for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal); end loop; end if; / SQL> start /tmp/p6.sql 10 CLARK 2695 KING 5500 MILLER 1430
PL/SQL procedure successfully completed.
SQL> 可以將sal列原值一起輸出做比較 [oracle@yang ~]$ vi /tmp/p6.sql
declare vdeptno number; begin vdeptno:=&1; if vdeptno=10 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.1); end loop; elsif vdeptno=20 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.2); end loop; elsif vdeptno=30 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.3); end loop; else for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal); end loop; end if; / SQL> start /tmp/p6.sql 10 CLARK 2450 2695 KING 5000 5500 MILLER 1300 1430
PL/SQL procedure successfully completed.
SQL>
SQL> start /tmp/p6.sql 20 SMITH 800 960 JONES 2975 3570 SCOTT 3000 3600 ADAMS 1100 1320 FORD 3000 3600
PL/SQL procedure successfully completed.
SQL> start /tmp/p6.sql 30 ALLEN 1600 2080 WARD 1250 1625 MARTIN 1250 1625 BLAKE 2850 3705 TURNER 1500 1950 JAMES 950 1235
PL/SQL procedure successfully completed.
SQL> 將if迴圈轉換為when迴圈 [oracle@yang ~]$ vi /tmp/p6.sql
declare vdeptno number; begin vdeptno:=&1; case vdeptno when 10 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.1); end loop; when 20 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.2); end loop; when 30 then for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal*1.3); end loop; else for a in (select ename,sal from emp where deptno=vdeptno) loop dbms_output.put_line(rpad(a.ename,15,' ')||' '||a.sal||' '||a.sal); end loop; end case; end; / SQL> start /tmp/p6.sql 10 CLARK 2450 2695 KING 5000 5500 MILLER 1300 1430
PL/SQL procedure successfully completed.
SQL> |
以EMP表中的empno 得到sal,建立函式
SQL> create or replace function getsal(vempno number) 2 return number 3 is 4 vsal number; 5 begin 6 select sal into vsal from emp where empno=vempno; 7 return vsal; 8 end getsal; 9 / Function created.
SQL> SQL> select getsal(7839) from dual;
GETSAL(7839) ------------ 5000
SQL>
SQL> select sal from emp where empno=7839;
SAL ---------- 5000
SQL> 如果想得到的結果為兩列那麼 SQL> create or replace function getsal(vempno number) 2 return varchar2 3 is 4 vname varchar2(20); 5 vsal number; 6 begin 7 select ename,sal into vename,vsal from emp where empno=vempno; 8 return (rpad(vname,15,’ ‘)||’ ‘||to_char(vsal)); 9 end getsal; 10 / SQL> [oracle@yang ~]$ vi /tmp/p9.sql
create or replace function getsal(vempno number) return varchar2 is vename varchar2(20); vsal number; begin select ename,sal into vename,vsal from emp where empno=vempno; return (rpad(vename,15,' ')||' '||to_char(vsal)); end getsal; / SQL> select getsal(7839) from dual;
GETSAL(7839) -------------------------------------------------------------------------------- KING 5000
SQL>
|
使用過程實現函式功能
SQL> create or replace procedure gsal(vempno in number) 2 is 3 vename varchar2(15); 4 vsal number; 5 begin 6 select ename,sal into vename,vsal from emp where empno=vempno; 7 dbms_output.put_line(vename||' '||vsal); 8 end gsal; 9 /
Procedure created.
SQL> SQL> set serveroutput on; SQL> execute gsal(7839); KING 5000
PL/SQL procedure successfully completed.
SQL> |
每輸出一次員工編號就將該員工的薪水上漲500並返回值
[oracle@yang ~]$ vi /tmp/p10.sql
create or replace procedure gsal(vempno in number) is vename varchar2(15); vsal number; begin update emp set sal=sal+500 where empno=vempno; commit; select ename,sal into vename,vsal from emp where empno=vempno; dbms_output.put_line(vename||' '||vsal); end gsal; / SQL> execute gsal(7839); KING 5500
PL/SQL procedure successfully completed.
SQL> |
實現在一串數字前選幾個字元加入()-
[oracle@yang ~]$ vi /tmp/p11.sql
create or replace procedure phone(vno in out varchar2) is begin vno:=' ('||substr(vno,1,length(vno)-8)||')-'||substr(vno,-8); end phone; / [oracle@yang ~]$ vi /tmp/p12.sql
declare vno varchar2(20):='&1'; begin phone(vno); dbms_output.put_line(vno); end; / ~ SQL> start /tmp/p12.sql 02812345678 (028)-12345678
PL/SQL procedure successfully completed.
SQL> SQL> start /tmp/p12.sql 028123456789 (0281)-23456789
PL/SQL procedure successfully completed.
SQL> |
包的使用
建立包定義一個函式查詢表emp的ename,sal列,定義一個過程輸入empno就將該員工薪水增加500.
建立包頭 SQL> create or replace package p1 is 2 function gsal(vempno number) return varchar2; 3 procedure usal(vempno number); 4 end p1; 5 /
Package created.
SQL> 建立包體 SQL> create or replace package body p1 2 is 3 function gsal(vempno number) 4 return varchar2 is 5 vename varchar2(20); 6 vsal number; 7 begin 8 select ename,sal into vename,vsal from emp where empno=vempno; 9 return (rpad(vename,15,' ')||' '||to_char(vsal)); 10 end gsal; 11 procedure usal(vempno in number) 12 is 13 begin 14 update emp set sal=sal+500 where empno=vempno; 15 commit; 16 end usal; 17 end p1; 18 /
Package body created.
SQL> 驗證 SQL> select p1.gsal(7566) from dual;
P1.GSAL(7566) -------------------------------------------------------------------------------- JONES 3475
SQL> exec p1.usal(7566);
PL/SQL procedure successfully completed.
SQL> select p1.gsal(7566) from dual;
P1.GSAL(7566) -------------------------------------------------------------------------------- JONES 3975
SQL> |
觸發器的使用
記錄所有登陸scott使用者的使用者名稱與時間
建立記錄表logt SQL> create table logt(uname varchar2(15),utime date);
Table created.
SQL> 登陸scott使用者 SQL> conn scott/tiger Connected. SQL> conn scott/tiger Connected. 查詢表 SQL> select uname,to_char(utime,'yyyy-mm-dd hh24:mi:ss') utime from logt;
UNAME UTIME --------------- ------------------- SCOTT 2014-05-04 08:19:11 SCOTT 2014-05-04 08:21:34
SQL>
|
當emp表中sal變動時,將舊的資料與新的資料都保留在表empsal中
建立記錄表 SQL> create table empsal as select sal osal,sal nsal from emp where 0=1;
Table created.
SQL> 建立觸發器 SQL> create or replace trigger emp_trig 2 before insert or update or delete of sal on emp for each row 3 begin 4 insert into empsal values(:old.sal,:new.sal); 5 end emp_trig; 6 /
Trigger created.
SQL> 驗證 SQL> update emp set sal=sal+1 where empno=7566;
1 row updated.
SQL> select * from empsal;
OSAL NSAL ---------- ---------- 3975 3976
SQL> insert into emp(empno,ename,sal) values(3588,'A11',2000);
1 row created.
SQL> select * from empsal;
OSAL NSAL ---------- ---------- 3975 3976 2000
SQL> delete emp where empno=3588;
1 row deleted.
SQL> select * from empsal;
OSAL NSAL ---------- ---------- 3975 3976 2000 2000
SQL> |
實現替代觸發
更新檢視不成功 SQL> create view v1 as select deptno,min(sal) msal from emp group by deptno;
View created.
SQL> select * from v1;
DEPTNO MSAL ---------- ---------- 30 950 20 800 10 1300
SQL> update v1 set msal=msal+1 where masl=950; update v1 set msal=msal+1 where masl=950 * ERROR at line 1: ORA-00904: "MASL": invalid identifier
SQL>
建立觸發器 SQL> create or replace trigger v1_trig 2 instead of insert or update or delete on v1 3 begin 4 update emp set sal=:old.msal+1 where sal=:old.msal; 5 end; 6 /
Trigger created.
SQL> 更新檢視v1 SQL> select * from v1;
DEPTNO MSAL ---------- ---------- 30 950 20 800 10 1300
SQL> update v1 set msal=msal+1 where msal=950;
1 row updated.
SQL> select * from v1;
DEPTNO MSAL ---------- ---------- 30 951 20 800 10 1300
SQL> |
對於平常對PL/SQL的檢查
SQL> select object_name,object_type,status from user_objects where object_type in ('FUNCTION','PROCEDURE','TRIGGER','PACKAGE BODY') and status <>'VALID';
no rows selected
SQL> 模擬錯誤 [oracle@yang ~]$ vi /tmp/p9.sql
create or replace function getsal(vempno number) return varchar2 is vename varchar2(20); vsal number; begin select ename,sal into vename,vsala from emp where empno=vempno; return (rpad(vename,15,' ')||' '||to_char(vsal)); end getsal; / SQL> start /tmp/p9.sql
Warning: Function created with compilation errors.
SQL> 再次查詢 SQL> select object_name,object_type,status from user_objects where object_type in ('FUNCTION','PROCEDURE','TRIGGER','PACKAGE BODY') and status <>'VALID';
OBJECT_NAME -------------------------------------------------------------------------------- OBJECT_TYPE STATUS ------------------- ------- GETSAL FUNCTION INVALID
SQL> 對於有問題的函式編譯檢視錯誤 SQL> alter function getsal compile;
Warning: Function altered with compilation errors.
SQL> show error Errors for FUNCTION GETSAL:
LINE/COL ERROR -------- ----------------------------------------------------------------- 7/1 PL/SQL: SQL Statement ignored 7/31 PLS-00201: identifier 'VSALA' must be declared 7/37 PL/SQL: ORA-00904: : invalid identifier SQL> SQL> select text from user_source where name='GETSAL'; (有時原始碼會加密,導致無法看懂,只能找開發人員解決)
TEXT -------------------------------------------------------------------------------- function getsal(vempno number) return varchar2 is vename varchar2(20); vsal number; begin select ename,sal into vename,vsala from emp where empno=vempno; return (rpad(vename,15,' ')||' '||to_char(vsal)); end getsal;
9 rows selected.
SQL> 找到問題修改在執行。
|
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29532781/viewspace-1174625/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle PL/SQL迴圈示例OracleSQL
- Oracle PL/SQLOracleSQL
- Oracle PL/SQL INDICESOracleSQL
- oracle pl/sql programmingOracleSQL
- Oracle PL/SQL編寫PL/SQL程式碼的注意事項OracleSQL
- ORACLE之常用FAQ:SQL&PL/SQLOracleSQL
- Oracle PL/SQL塊簡介OracleSQL
- Oracle PL/SQL中EXCEPTION用法OracleSQLException
- Oracle PL/SQL 之 函式OracleSQL函式
- PL/SQL Developer 連線 OracleSQLDeveloperOracle
- oracle INDEX BY Pl/sql陣列OracleIndexSQL陣列
- 【PL/SQL】oracle建立dblinkSQLOracle
- Oracle PL/SQL之GROUP BY CUBEOracleSQL
- 【Oracle】--PL/SQL匯入Oracle sql指令碼"傻瓜教程"OracleSQL指令碼
- Oracle 的PL/SQL語言使用OracleSQL
- Oracle PL/SQL之 Package介紹OracleSQLPackage
- oracle PL/SQL中的過載OracleSQL
- Oracle PL/SQL語言基礎OracleSQL
- 【Oracle】Windows安裝pl/sql developerOracleWindowsSQLDeveloper
- oracle dbms_profiles分析pl/sqlOracleSQL
- Oracle 11g系列:SQL Plus與PL/SQLOracleSQL
- Oracle PL/SQL 優化與調整 – PL/SQL Native Compilation 說明OracleSQL優化
- oracle pl/sql儲存過程內外層遊標cursor巢狀引數化示例OracleSQL儲存過程巢狀
- 使用profiler測試Oracle PL/SQL效能OracleSQL
- Oracle Pl/SQL 之 儲存過程OracleSQL儲存過程
- Oracle之PL/SQL基礎學習OracleSQL
- Oracle PL/SQL語言基礎(轉)OracleSQL
- 【SQL/PLUS】Oracle PL/SQL程式設計用set serveroutput onSQLOracle程式設計Server
- PL/SQLSQL
- Oracle PL/SQL程式碼中的註釋OracleSQL
- Oracle PL/SQL 關於遊標的介紹OracleSQL
- Oracle PL/SQL 自治事務的說明OracleSQL
- 【PL/SQL】Oracle--樹的使用(Connect By)SQLOracle
- SQL&PL/SQL (轉)SQL
- PL/SQL 宣告SQL
- PL/SQL cursorSQL
- PL/SQL打包SQL
- PL/SQL DEVSQLdev