PL/SQL详例和解释(二)

2015-01-25 19:54:28 · 作者: · 浏览: 29
in 1..100 loop v_counter:=v_counter+1; if v_counter=10 then commit; v_counter:=0; end if; end loop; end; --ROLLBACK和SAVEPOINT select * from chap4; create table chap4 (id number,name varchar2(20)); create sequence chap4_seq increment by 5; declare v_name varchar2(30); v_id number; begin select first_name||'.'||last_name fullname into v_name from it_employees where salary=(select max(salary) from it_employees); insert into chap4 (id, name)values(chap4_seq.nextval,v_name); savepoint A; select first_name||'.'||last_name fullname into v_name from it_employees where salary=(select min(salary) from it_employees); insert into chap4 (id, name)values(chap4_seq.nextval,v_name); savepoint B; select first_name||'.'||last_name fullname into v_name from it_employees where employee_id=10003; insert into chap4 (id, name)values(chap4_seq.nextval,v_name); savepoint C; select job_id into v_id from it_employees where employee_id=10003; DBMS_OUTPUT.put_line('JOB ID is: '||v_id); rollback to savepoint A; end; select * from chap4; delete chap4; --比较两个数值大小 declare large_num number:=&number1; small_num number:=&number2; temp_num number; begin if large_num=20000 then v_level:='A'; when v_salary>=18000 then v_level:='B'; when v_salary>=15000 then v_level:='C'; when v_salary>=12000 then v_level:='D'; when v_salary>=10000 then v_level:='F'; else v_level:='E'; end case; dbms_output.put_line('This employee salary level is '||v_level); end case; end; --NULLIF函数查看奇偶 declare v_num number:=&Input_Number; v_res number; begin v_res:=nullif(mod(v_num,2),0); DBMS_OUTPUT.PUT_LINE('result is '||v_res); end; --序列递增 create sequence seq_num increment by 1; drop SEQUENCE seq_num; begin loop DBMS_OUTPUT.PUT_LINE('No.'||seq_num.nextval); exit when seq_num.currval=100; end loop; end; --简单的红绿灯问题 declare s_timer_green number(10):=20; s_timer_red number(10):=30; v_trigger boolean:=&Trigger; begin while s_timer_green!=0 loop dbms_output.put_line('Allow Crossing the Road, and remaining time is: '||s_timer_green); s_timer_green:=s_timer_green-1; end loop; DBMS_OUTPUT.PUT_LINE('Cannot Cross the Road any more! Please wait for red light!'); while s_timer_red!=0 loop dbms_output.put_line('Cannot Cross the Road, wait for time: '||s_timer_red); s_timer_red:=s_timer_red-1; if (v_trigger = true) and (s_timer_red<=5)--exit when then exit; end if; end loop; end; --逆向相乘 declare v_num number(20):=1; begin for counter in reverse 1..10 loop v_num:=v_num*counter; DBMS_OUTPUT.PUT_LINE('v_num: '||v_num); end loop; DBMS_OUTPUT.PUT_LINE('the final v_num: '||v_num); end; --1--100每10个数字求和 declare v_num number:=0; v_sum number; v_counter number:=0; begin v_sum:=v_num; loop v_counter:=v_counter+1; v_num:=v_num+1; v_sum:=v_sum+v_num; continue when v_counter<10;--if v_counter<10 then continue; end if; DBMS_OUTPUT.PUT_LINE('sum is: '||v_sum); v_counter:=0; v_sum:=0; if v_num=100 then exit; end if; end loop; end; --*状三角形 declare begin for i in 1..10 loop for j in 1..i loop dbms_output.put('*'); DBMS_OUTPUT.PUT(' '); end loop; DBMS_OUTPUT.PUT_LINE(''); end loop; end; --内部异常处理和用户定义异常处理 declare v_dep_id number(3); v_name varchar2(30); e_dep_id exception; begin v_dep_id:=&Department_ID; if v_dep_id<0 then raise e_dep_id; end if; select first_name||' '||last_name into v_name from it_employees e, departments d where e.department_id=d.department_id and d.department_id=v_dep_id; dbms_output.put_line('The name of this student is: '||v_name); exception when e_dep_id then dbms_output.put_line('The department id cannot be negative!'); when no_data_found then dbms_output.put_line('There is not any record for this student!'); when too_many_rows then dbms_output.put_line('Returns one more student records!'); when value_error or invalid_number then dbms_output.put_line('Error occurs for values!'); end; --当PL/SQL语句块儿的声明部分出现运行时的错误时,该语句块儿的异常处理部分不能捕获此项错误。 --再次抛出异常 declare v_num number(10); e_v_num exception; begin begin v_num:=&In_num; if v_num<0 then raise e_v_num; else DBMS_OUTPUT.PUT_LINE('Number is: '||v_num); end if; exception when e_v_num then raise; end; exception when e_v_num then dbms_output.put_line('The value cannot be negative!'); end; --Raise_application_error() declare count_total number; begin select count(*) into count_total from it_employees where department_id=&department_id; if count_total>
1 then raise_application_error(-20000,'The number of employee in this department is invaild!'); end if; end; --SQLCODE 和 SQLEERM declare num number(2); error_number number; error_msg varchar2(200); begin num:=# dbms_output.put_line(num); exception when others then error_number:=SQLCODE; error_msg:=substr(SQLERRM,1,200); dbms_output.put_line('Error Code: '||error_number); dbms_output.put_line('Error Message: '||error_msg); end; --简单的显式游标 select * from it_employees; declare cursor c_it_emp is select * from it_employees where employee_id<=10003; emp_info it_employees%rowtype; begin open c_it_emp; loop fetch c_it_emp into emp_info; exit when c_it_emp%notfound; dbms_output.put_line(emp_info.first_name||'.'||emp_info.last_name||' '||emp_info.e_mail); end loop; close c_it_emp; end; --用户自己定义类型 declare cursor c_it_emp is select first_name,last_name,e_mail from it_employees where employee_id<=10003; type emp_info is record (firstname it_employees.first_name%type, lastname it_employees.last_name%type, email it_employees.e_mail%type); emp_information emp_info; begin open c_it_emp; loop fetch c_it_emp into emp_information; exit when c_it_emp%notfound; DBMS_OUTPUT.PUT_LINE(emp_information.firstname||'.'||emp_information.lastname||',email is: '||emp_information.email); end loop; close c_it_emp; exception when others then if c_it_emp%isopen then close c_it_emp; end if; end; --游标FOR循环实现部门人数 declare dep_id it_employees.department_id%type; cursor c_emp_info is select * from it_employees where department_id=dep_id; begin dep_id:=&department_id; for emp_info in c_emp_info loop dbms_output.put_line(emp_info.first_name||'.'||emp_info.last_name); end loop; exception -- when no_data_found then dbms_output.put_line('There is not any employees from this department!'); when value_error then dbms_output.put_line('ERROR on input data!!!'); end; select * from departments; --嵌套CURSOR实现查看部门人员 declare dep_id it_employees.department_id%type; cursor c_loc_id is select department_id,department_name from departments where location_id=&Location_id; cursor c_emp_name is select first_name||'.'||last_name name from it_employees where department_id=dep_id; begin for loc_id in c_loc_id loop dep_id:=loc_id.department_id; dbms_output.put('Employees who are in '||loc_id.department_name||': '); for emp_name in c_emp_name loop dbms_output.put(emp_name.name||'; '); end loop; dbms_output.put_line(''); end loop; end; --嵌套的带参CURSOR实现所有员工信息输出 declare cursor c_emp_info is select employee_id, first_name||'.'||last_name name, department_id from it_employees; cursor c_dep_info (dep_id in departments.department_id%type) is select department_name from departments where departments.department_id=dep_id; begin for emp_info in c_emp_info loop dbms_output.put(emp_info.employee_id||' '||emp_info.name||' '); for dep_info in c_dep_info(emp_info.department_id) loop dbms_output.put(dep_info.department_name); end loop; dbms_output.put_line(''); end loop; end; --Before Trigger 实现插入新员工并分配给一个manager。 create or replace trigger emp_insert_bi before insert on it_employees for each row declare v_emp_id it_employees.employee_id%type; begin select max(employee_id)+1 into v_emp_id from it_employees; :new.employee_id:=v_emp_id; :new.salary:=10000; :new.manager_id:=10001; end; insert into it_employees (first_name, last_name, e_mail, phone_number, job_id, birth_date, department_id) values ('Lily','Black','Lily.B@oracle.com',10163735464,1002,'30-5月 -89',101); delete from it_employees where employee_id=(select max(employee_id) from it_employees); drop trigger emp_insert_bi; --After Trigger实现对员工表操作的记录 create table statistics (record_id number(10), table_name varchar2(30), transaction_name varchar2(10), transaction_user varchar2(30), transaction_date date);--创建记录表 create or replace trigger tab_stat--创建触发器 after insert or delete on it_employees declare v_id statistics.record_id%type; v_type varchar2(10); v_count number(10); PRAGMA autonomous_transaction; begin select count(*) into v_count from statistics; if v_count=0 then v_id:=1; else select max(record_id)+1 into v_id from statistics; end if; if inserting then v_type:='Insert'; elsif deleting then v_type:='Delete'; end if; insert into statistics (record_id, table_name, transaction_name, transaction_user, transaction_date) values (v_id,'it_employees',v_type,user,sysdate); commit; end; select * from STATISTICS order by record_id asc;--查看 delete from STATISTICS; --触发器实现办公时间! create or replace trigger check_date before insert or delete or update on it_employees declare v_date_day varchar2(30); v_date_time number(10); begin v_date_day:=rtrim(to_char(sysdate, 'DAY')); v_date_time:=to_number(to_char(sysdate, 'HH24')); if v_date_day like 'S%' then raise_application_error(-20001,'Today is Weekend, it is invaild day to operate tables!'); else if v_date_time<9 or v_date_time>=18 then raise_application_error(-20002,'Invaild time to operate tables!'); end if; end if; end; update it_employees set salary=11000 where employee_id=10009; drop trigger check_date; --复合触发器实现对表IT_EMPLOYEES的插入和更新 create table operation_record (record_id numb