oracle pl/sql(一)

2014-04-13sql

1.pl/sql分匿名塊和命名塊數據庫

匿名塊語法:oracle

DECLAREide

     declaration statements函數

BEGINoop

    executable statments指針

EXCEPTIONserver

    exception-handing statments   ---異常處理內存

END;ci

命名塊:存儲過程,函數,觸發器,包等。

2.pl/sql語句塊分三部分:

1)聲明部分:

2)可執行部分:

3)異常處理部分:

其中可執行部分是語句塊中惟一要求必須存在的部分,聲明部分和異常處理部分是可選的。

3.聲明變量

1)語法:

identifier [CONSTANT] datatype [NOT NULL] [:=value |DEFAULT expr];

2)示例一

declare

v_first_name varchar2(50);

c_count constant number :=0; ----常量

v_hiredate date;

v_vaild BOLLEAN NOT NULL DEFAULT TRUE;

//顯示僱員的姓名,工資,我的所得稅

set serveroutput on;


declare

v_ename varchar2(20);

v_sal   number(6,2);

v_tax_rate constant number(3,2) :=0.06; ---稅率

v_tax_sal  number(6,2);


begin 

select ename,sal into v_ename,v_sal from emp where empno = &no;

v_tax_sal := v_sal * v_tax_rate;   ---賦值


dbms_output.put_line('v_ename: ' || v_ename);

dbms_output.put_line('v_sal: ' || v_sal);

dbms_output.put_line('v_tax_sal: ' || v_tax_sal);

end;

3)示例二(和一聲明變量方法不同)

declare 

v_ename emp.ename%type;

v_sal emp.sal%type;

v_tax_rate constant number(3,2) :=0.06; ---稅率

v_tax_sal  number(6,2);


begin 

select ename,sal into v_ename,v_sal from emp where empno = &no;

v_tax_sal := v_sal * v_tax_rate;   ---賦值


dbms_output.put_line('v_ename: ' || v_ename);

dbms_output.put_line('v_sal: ' || v_sal);

dbms_output.put_line('v_tax_sal: ' || v_tax_sal);

end;

4.標識符的命名規則

1)定義變量,建議用v_,如v_ename

2)定義常量,建議用c_,如c_tax_rate

3)定義遊標,建議使用_cursor做爲後綴,如emp_cursor

4)定義表類型,建議使用_table_type做爲後綴,如sal_table_type

5)定義表變量,建議使用_table做爲後綴,如sal_table

5.PL/SQL編譯過程步驟

編譯過程包括語法檢查,綁定以及僞代碼生成。語法檢查涉及檢查PL/SQL代碼中的編譯錯誤。在糾正語法錯誤以後,會給每一個變量分配內存地址,以保存ORACLE數據,這個過程稱爲綁定。接下來,會產生PL/SQL語句塊的僞代碼,僞代碼是PL/SQL引擎的指令列表,對於命名語句塊,僞代碼會存儲在數據庫中,並在程序下一次執行時使用。

6.替代變量

在匿名PL/SQL塊中接受輸入參數使用&或者&&做爲替代變量

7.初始化變量用select into 語法

//求emp表中的平均工資

set serveroutput on;

declare

v_sal   number(6,2);

begin 

select avg(sal) into v_sal from emp;

dbms_output.put_line('v_sal: ' || v_sal);

end;

##在sqlplus中執行最後要加/。

8.if 語句

1)if 語法:

IF condition THEN

   statements;

[ELSIF condition THEN

  statements;]

[ELSE 

  statements;

]

END IF;

2)示例:

//若是工資小於2000,把僱員的薪水加50

set serveroutput on;

DECLARE

  v_sal emp.sal%TYPE;

BEGIN

  SELECT sal into v_sal FROM emp where lower(ename)=lower('&name');

  if v_sal<2000 then

  update emp set sal=sal+50 where lower(ename)=lower('&name');

  end if;

  dbms_output.put_line('v_sal: ' || v_sal);

END;

##驗證

SELECT * from emp where sal<2000;

//若是job=PRESIDENT,sal=sal+200;job=MANAGER ,sal=sal+1000;other ,sal=sal+100

&empno


set serveroutput on;

DECLARE

  v_sal EMP.SAL%type;

  v_job EMP.JOB%type;

  v_empno EMP.EMPNO%TYPE;

BEGIN

  SELECT job,sal,empno into v_job,v_sal,v_empno FROM emp where empno=&no;

  if v_job='PRESIDENT' then

  update emp set sal=sal+200 where empno=v_empno;

  elsif v_job='MANAGER' then

  update emp set sal=sal+1000 where empno=v_empno;

  else

  update emp set sal=sal+100 where empno=v_empno;

  end if;

  DBMS_OUTPUT.PUT_LINE('v_job: '|| v_job);

  DBMS_OUTPUT.PUT_LINE('v_sal:' || v_sal);

  COMMIT;

END;

ROLLBACK; --回滾

##驗證

SELECT * from emp where empno=7566;

9.循環語句

1)loop循環

loop 

   statements;

exit [when condition];

end loop;

//示例

create table tmp01 (id int);

declare i int :=1;

begin

loop

insert into tmp01 values(i);

commit;

exit when i>100;

i :=i+1;

end loop;

end;

select * from tmp01;

2)while 循環

while condition loop

statement1;

statement2;

..........

end loop;

//示例

create table tmp01 (id int);

declare i int :=1;

begin

while i<=100 loop

insert into tmp01 values(i);

i :=i+1;

end loop;

commit; ----批量提交

end;

select * from tmp01;

3)for 循環

for counter in [reverse] lower_bound .. upper_bound loop

statement1;

statement2;

........

end loop;

##counter變量不須要定義 

//示例

drop table tmp01 purge;

create table tmp01 (id int);

begin

for i in 1..100 loop

insert into tmp01 values(i);

end loop;

commit;

end;

select * from tmp01;

4)case

//用替代變量輸入部門號,使用case語句判斷條件更新僱員工資

部門號爲10,僱員加薪10%

部門號爲20,僱員加薪8%

部門號爲30,僱員加薪15%

若是輸入其餘數字,則顯示「該部門不存在」


set serveroutput on;

DECLARE

v_deptno emp.deptno%type;


begin

v_deptno :=&deptno;

case 

when v_deptno=10 then

update emp set sal=sal*1.1 where deptno=v_deptno;

when v_deptno=20 then

update emp set sal=sal*1.08 where deptno=v_deptno;

when v_deptno=30 then

update emp set sal=sal*1.15 where deptno=v_deptno;

else

dbms_output.put_line('no such department');

end case;

end;


10.SQL遊標

當執行select,insert,update,delete 時oracle會爲SQL語句分配相應的上下文區(context area).oracle使用上下區解析並執行相應的SQL語句,而遊標就是指向上下文區的指針。

遊標包括隱式遊標和顯示遊標。其中隱式遊標也稱爲SQL遊標,專門用於處理select into,insert,update,delete語句。顯示遊標用於處理多行select語句。

SQL遊標屬性:sql%found,sql%notfound,sql%rowcount,sql%isopen等

1)sql%isopen:用於肯定SQL遊標是否打開。

2)sql%found/sql%notfound:用於肯定SQL語句是否執行成功。

set serveroutput on;

declare 

v_deptno emp.deptno%type := &no;

begin

update emp set sal = sal*1.05 where deptno=v_deptno;

if sql%notfound then

dbms_output.put_line('deptno is not exist.');

else 

dbms_output.put_line('sql execute successful.');

end if;

end;

3)sql%rowcount:用於返回sql語句所做用的總計行數。

set serveroutput on;

declare 

v_deptno emp.deptno%type := &no;

begin

update emp set sal = nvl(sal,0)*1.05 where deptno=v_deptno;

dbms_output.put_line('have '|| sql%rowcount || ' row changed.');

if sql%notfound then

dbms_output.put_line('deptno is not exist.');

else 

dbms_output.put_line('sql execute successful.');

end if;

end;

4)案例

用替代變量輸入客戶名(不區分大小寫)和所在城市,並修改客戶所在城市,若是客戶不在,則顯示「該客戶不在」

##建立表

create table customer(customer_id number not null,customer_name varchar2(50),

city_name varchar2(50),constraint pk_customer primary key(customer_id));

##插入數據

 insert into customer values(1,'yangry','henan');

 insert into customer values(2,'lisn','shangqiu');

 insert into customer values(3,'lij','nanyang');

 insert into customer values(4,'guoyf','luoyang');


 set serveroutput on;

 declare

 v_uname CUSTOMER.CUSTOMER_NAME%TYPE;

 v_cname CUSTOMER.CITY_NAME%TYPE;

 begin

 v_uname :='&uname';

 v_cname :='&cname';

 update customer set city_name=v_cname where upper(customer_name)=upper(v_uname);

 if sql%notfound then

 dbms_output.put_line('the customer is not exist');

 end if;

 commit;

 end;

//另外一種聲明變量的方法

 v_uname CUSTOMER.CUSTOMER_NAME%TYPE :='&uname';

 v_cname CUSTOMER.CITY_NAME%TYPE  :='&cname';

 

//begin後也可修改成:

 select customer_name into v_uname from customer where upper(customer_name) = '&uname';

 v_cname :='&cname';--此句不能用select的緣由跟下面的set語句有關。

相關文章
相關標籤/搜索