oracle pl/sql(一)

2014-04-13

1.pl/sql分匿名块和命名块

匿名块语法:

DECLARE

     declaration statements

BEGIN

    executable statments

EXCEPTION

    exception-handing statments   ---异常处理

END;

命名块:存储过程,函数,触发器,包等。

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语句有关。


你可能感兴趣的:(oracle pl/sql(一))