1. 程式人生 > >Oracle資料庫plsql簡單程式設計

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(20default '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 過程已成功完成。