Oracle資料庫plsql簡單程式設計
工具:cmd sqlplus
內容:基本表的操作,plsql程式設計(分支結構,迴圈,判斷等)
賬戶:scott
前期準備
cmd使用小技巧
由於筆者使用的是sqlplus,且是在cmd環境下進入的。cmd環境的文字編輯不太容易,故提供大家一點小技巧。
如圖:
cmd 快捷鍵:alt+space+k 標記
選定區域後enter複製
alt+space+p 貼上
!!!!標記可以選定任意範圍,相比office中選定多行的固定模式超級好用有木有!!!
C:\Users\Administrator>sqlplus
SQL*Plus: Release 11.2.0.1.0 Production on 星期四 4月 26 08:13:18 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
請輸入使用者名稱: scott
輸入口令:
ERROR:
ORA-12560: TNS: 協議介面卡錯誤
如果碰到協議介面卡錯誤,檢查下服務有沒有開啟。
請輸入使用者名稱: scott
輸入口令:
連線到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from user_role_privs;
USERNAME GRANTED_ROLE ADM DEF OS_
SCOTT CONNECT NO YES NO
SCOTT RESOURCE NO YES NO
SQL> select sysdate,systimestamp from dual;
SYSDATE
SYSTIMESTAMP
26-4月 -18
26-4月 -18 08.20.24.358000 上午 +08:00
正文:
SQL> print sname;
SP2-0552: 未宣告繫結變數 "SNAME"。
SQL> set serveroutput on
SQL> declare
2 sname varchar2(20) :='abcd';
3 begin
4 sname :=sname||'and tom';
5 dbms_output.put_line(sname);
6 end;
7 /
abcdand tom
PL/SQL 過程已成功完成。
SQL> declare
2 ename varchar2(20) default 'abc';
3 begin
4 select sname into ename from student where sno ='2015
SQL>set serveroutput on
SQL>declare
2 pi constant number :=3.14;
3 r number default 3;
4 area nubmer;
5 begin
6 area :=pi*r*r;
7 dbms_output.put_line(area);
8 end;
9 /
****
PL/SQL 過程已成功完成
SQL>var emp_name varchar2(30);
SQL>begin
2 select sname into : emp_name from student where sno='2018001';
3 end;
4 /
SQL> insert into student values('2018001','zhangsan','男','20');
已建立 1 行。
SQL> select * from student;
SNO SNAME SSEX SAGE
---------- -------------------- -------------------- ----------
2018001 zhangsan 男 20
SQL> var emp_name varchar2(30);
SQL> begin
2 select sname into :emp_name from student where sno='2018001';
3 end;
4 /
PL/SQL 過程已成功完成。
SQL> print emp_name;
EMP_NAME
--------------------------------
zhangsan
----------
//修改scott賬戶許可權
在plsql developer中要是以scott/tiger登入時提示ora-28000 the account is locked。
解決辦法:
新裝完Oracle10g後,用scott/tiger測試,會出現以下錯誤提示:
oracle10g the account is locked
oracle10g the password has expired
原因:預設Oracle10g的scott不能登陸。
解決:
(1)conn sys/sys as sysdba; //以DBA的身份登入
(2)alter user scott account unlock;// 然後解鎖
(3)conn scott/tiger //彈出一個修改密碼的對話方塊,修改一下密碼就可以了
在執行裡面輸入cmd在DOS模式下輸入sqlplus,以system使用者名稱登入,密碼是剛裝oracle時自己填寫的密碼orcl,登入進去以後。
SQL> conn sys/sys as sysdba; (分號是必須的但是我是以system登入的所在這不應該寫conn sys/sys as sysdba應該寫conn system/orcl as sysdba;)
Connected.
SQL> alter user scott account unlock;
User altered.
SQL> commit;
Commit complete.
SQL> conn scott/tiger//請輸入新密碼,並確認後OK
Password changed
Connected.
----------
SQL> update student set sname='張三' where sno='2018001';
已更新 1 行。
SQL> select * from student;
SNO SNAME SSEX SAGE
---------- -------------------- -------------------- ----------
2018001 張三 男 20
SQL>
SQL> declare
2 myemp student%rowtype;
3 begin
4 select * into myemp from student where sno='2018001';
5 dbms_output.put_line(myemp.sname);
6 end;
7 /
zhangsan
----------
//查詢james工資,如果大於900,則發放獎金若干
declare emp.sal % type;
//定義變數,與sal欄位型別保持一致
select sal into newSal from emp
where ename='james';
if newSal>900 then
update emp
set comm=800
where ename='james';
end if;
commit;
end;
----------
//if else
SQL> declare
2 newSal emp.sal % type;
3 begin
4 select sal into newSal from emp where ename='ALLEN';
5 if newSal > 1000 then
6 update emp set comm = 800 where ename ='ALLEN';
7 else
8 update emp set comm = 400 where ename ='ALLEN';
9 end if;
10 end;
11 /
PL/SQL 過程已成功完成。
SQL> select * from emp;
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
SMITH 800
ALLEN 1600 800
WARD 1250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500 0
ADAMS 1100
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
JAMES 950
FORD 3000
MILLER 1300
已選擇14行。
----------
//選擇結構
SQL> set serveroutput on
SQL>
SQL> declare
2 v_grade char(1):=upper('&grade');
3 begin
4 case v_grade
5 when 'A' then
6 dbms_output.put_line('Excellent');
7 when 'B' then
8 dbms_output.put_line('Very Good');
9 when 'C' then
10 dbms_output.put_line('Good');
11 else
12 dbms_output.put_line('No such grade');
13 end case;
14 end;
15 /
輸入 grade 的值: a
原值 2: v_grade char(1):=upper('&grade');
新值 2: v_grade char(1):=upper('a');
Excellent
PL/SQL 過程已成功完成。
----------
//選擇結構
SQL> set serveroutput on
SQL> declare
2 v_grade char(1):=upper('&grade');
3 p_grade varchar(20);
4 begin
5 p_grade :=
6 case v_grade
7 when 'A' then
8 'Excellent'
9 when 'B' then
10 'Very Good'
11 when 'C' then
12 'Good'
13 else
14 'No such grade'
15 end;
16 dbms_output.put_line('Grade:'||v_grade||',the result is '||p_grade);
17 end;
18 /
輸入 grade 的值: a
原值 2: v_grade char(1):=upper('&grade');
新值 2: v_grade char(1):=upper('a');
Grade:A,the result is Excellent
PL/SQL 過程已成功完成。
----------
//loop迴圈 計算1+2+3+...+100的和
SQL> set serveroutput on
SQL>
SQL> declare
2 counter number(3):=0;
3 sumResult number:=0;
4 begin
5 loop
6 counter := counter+1;
7 sumResult :=sumResult+counter;
8 if counter>=100 then exit;
9 end if;
10 end loop;
11 dbms_output.put_line('result is:'||to_char(sumResult));
12 end;
13 /
result is:5050
PL/SQL 過程已成功完成。
----------
for迴圈
SQL> set serveroutput on
SQL> declare
2 counter number(3):=0;
3 sumResult number:=0;
4 begin
5 while counter<100 loop
6 counter:=counter+1;
7 sumResult:=sumResult+counter;
8 end loop;
9 dbms_output.put_line('result is:'||sumResult);
10 end;
11 /
result is:5050
PL/SQL 過程已成功完成。
----------
SQL> set serveroutput on
SQL> declare
2 sumsal emp.sal % type;
3 begin
4 select sum(sal) into sumsal from emp;
5 if sumsal>20000 then
6 goto first_label;
7 else
8 goto second_label;
9 end if;
10 <<first_label>>
11 dbms_output.put_line('ABOVE 20000:'||sumsal);
12 <<second_label>>
13 null;
14 end;
15 /
ABOVE 20000:29025
PL/SQL 過程已成功完成。
----------
SQL> select * from emp;
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
SMITH 800
ALLEN 1600 800
WARD 1250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500 0
ADAMS 1100
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
JAMES 950
FORD 3000
MILLER 1300
已選擇14行。
SQL> select sum(sal) from emp;
SUM(SAL)
----------
29025
----------
動態sql語句
SQL> declare
2 sql_stmt varchar(200);
3 begin
4 sql_stmt := 'insert into student values(:1,:2,:3,:4,:5)';
5 execute immediate sql_stmt using '2018003','wang','man','45','2000';
6 end;
7 /
PL/SQL 過程已成功完成。
SQL> select * from student;
SNO SNAME SSEX SAGE SSAL
---------- -------------------- -------------------- ---------- ----------
2018003 wang man 45 2000
2018001 張三 男 20
2018002 李四 男 30 200
----------
動態sql語句
SQL> set serveroutput on
SQL> declare
2 sql_stmt varchar2(200);
3 stu student%rowtype;
4 begin
5 sql_stmt :='select * from student where sno=:id';
6 execute immediate sql_stmt into stu using '2018001';
7 dbms_output.put_line(stu.sname);
8 end;
9 /
張三
----------
異常處理
SQL> set serveroutput on
SQL> declare
2 newvalue student.sno%type;
3 begin
4 select sno into newvalue from student;
5 exception
6 when
7 TOO_MANY_ROWS then
8 dbms_output.put_line('return too many rows');
9 when others then
10 dbms_output.put_line('unknown exception');
11 end;
12
13 /
return too many rows
----------
自定義異常
SQL> select * from emp;
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
SMITH 800
ALLEN 1600 800
WARD 1250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500 0
ADAMS 1100
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
JAMES 950
FORD 3000
MILLER 1300
已選擇14行。
SQL> set serveroutput on
SQL> declare
2 msal emp.sal%type;
3 myexp exception;
4 begin
5 select sal into msal from emp where ename='MARTIN';
6 if msal <5000 then
7 raise myexp;
8 end if;
9 exception
10 when NO_DATA_FOUND then
11 dbms_output.put_line('NO RECORDSET FIND');
12 when myexp then
13 dbms_output.put_line('SAL IS TOO LESS');
14 end;
15 /
SAL IS TOO LESS
PL/SQL 過程已成功完成。
----------
使用隱式遊標屬性判斷對僱員工資的修改是否成功
SQL> set serveroutput on
SQL> begin
2 update emp set sal=sal+2000 where ename='WARD';
3 if SQL%FOUND then
4 dbms_output.put_line('update success');
5 commit;
6 else
7 dbms_output.put_line('update fail');
8 end if;
9 end;
10 /
update success
PL/SQL 過程已成功完成。
----------
遊標
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
SMITH 800
ALLEN 1600 800
WARD 3250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500 0
ADAMS 1100
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
JAMES 950
FORD 3000
MILLER 1300
已選擇14行。
SQL> set serveroutput on
SQL> declare
2 v_ename varchar2(10);
3 v_job varchar2(10);
4 cursor emp_cursor is
5 select ename,sal from emp where comm =800;
6 begin
7 open emp_cursor;
8 fetch emp_cursor into v_ename,v_job;
9 dbms_output.put_line(v_ename||','||v_job);
10 close emp_cursor;
11 end;
12 /
ALLEN,1600
PL/SQL 過程已成功完成。
----------
排序
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
SMITH 800
ALLEN 1600 800
WARD 3250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
SCOTT 3000
KING 5000
TURNER 1500 0
ADAMS 1100
ENAME SAL COMM ID
-------------------- ---------- ---------- ----------
JAMES 950
FORD 3000
MILLER 1300
已選擇14行。
SQL> set serveroutput on
SQL> declare
2 v_ename varchar2(20);
3 v_sal number(5);
4 cursor emp_cursor is select ename,sal from emp order by sal desc;
5 begin
6 open emp_cursor;
7 for i in 1..3 loop
8 fetch emp_cursor into v_ename,v_sal;
9 dbms_output.put_line(v_ename||','||v_sal);
10 end loop;
11 close emp_cursor;
12 end;
13 /
KING,5000
WARD,3250
FORD,3000
PL/SQL 過程已成功完成。
----------
使用特殊的for迴圈,顯示全部僱員部分資訊
SQL> set serveroutput on
SQL> declare
2 cursor emp_cursor is
3 select sal,ename from emp;
4 begin
5 for emp_record in emp_cursor loop
6 dbms_output.put_line(emp_record.sal||','||emp_record.ename);
7 end loop;
8 end;
9 /
800,SMITH
1600,ALLEN
3250,WARD
2975,JONES
1250,MARTIN
2850,BLAKE
2450,CLARK
3000,SCOTT
5000,KING
1500,TURNER
1100,ADAMS
950,JAMES
3000,FORD
1300,MILLER
PL/SQL 過程已成功完成。
----------
帶引數的遊標
<font color=gray>
set serveroutput on
declare
v_eid number(5);
v_ename varchar2(20);
cursor emp_cursor (pid nubmer,jname varchar2) is
select sal,ename from emp
where sal =pid and ename=jname;
begin
open emp_cursor(1600,'ALLEN');
loop
fetch
emp_cursor into v_eid,v_ename;
exit when emp_cursor&NOTFOUND;
dbms_output.put_line(v_eid||','||v_ename);
end loop;
end;
/
</font>
----------
儲存過程
set serveroutput on
create or replace procedure pro_no_par is
begin
update emp set sal=sal+2000 where id=3;
commit;
dbms_output.put_line('sal is updated');
end pro_no_par;
/
已建立。
execute pro_no_par;
----------
帶有in的procudure
SQL> set serveroutput on
SQL> create or replace procedure pro_in_par
2 (var_1 in nvarchar2,var_2 in number)is
3 begin
4 update emp set sal=sal+var_2 where ename=var_1;
5 commit;
6 dbms_output.put_line(var_1||' sal is updated'||var_2||'yuan');
7 end pro_in_par;
8 /
過程已建立。
SQL> execute pro_in_par('SMITH',1500);
SMITH sal is updated1500yuan
PL/SQL 過程已成功完成。