标签:
[DECLARE declarations] --声明部分定义变量、游标和自定义异常 BEGIN executable statements --包含 SQL 和 PL/SQL 语句的可执行部分 [EXCEPTION handlers] --指定出现错误时需要执行的操作 END;
DECLARE qty_on_hand NUMBER(5); --声明部分定义变量、游标和自定义异常 BEGIN --begin到end 包含 SQL 和 PL/SQL 语句的可执行部分 SELECT quantity INTO qty_on_hand FROM Products WHERE product = ‘芭比娃娃‘ FOR UPDATE OF quantity; IF qty_on_hand > 0 THEN UPDATE Products SET quantity = quantity + 1 WHERE product = ‘芭比娃娃‘; INSERT INTO purchase_record VALUES (‘已购买芭比娃娃‘, SYSDATE); END IF; COMMIT; EXCEPTION /* 异常处理语句 */ --指定出现错误时需要执行的操作 WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(‘出错:‘|| SQLERRM); END;
identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];
DECLARE icode VARCHAR2(6); p_catg VARCHAR2(20); p_rate NUMBER; c_rate CONSTANT NUMBER := 0.10; BEGIN ... icode := ‘i205‘; SELECT p_category, itemrate * c_rate INTO p_catg, p_rate FROM itemfile WHERE itemcode = icode; ... END;
指定数值的存储格式
数据类型 |
SQL类型 |
PL/SQL类型 |
CHAR |
1~2000 |
1~32767 |
LONG |
1~2GB |
1~32760 |
LONG RAW |
1~2GB |
1~32760 |
RAW |
1~2000 |
1~32767 |
VARCHAR2 |
1~4000 |
1~32767 |
SET SERVEROUTPUT ON DECLARE clob_var CLOB; amount INTEGER; offset INTEGER; output_var VARCHAR2(100); BEGIN SELECT chapter_text INTO clob_var --从表中选择 CLOB 定位符到 clob_var变量中 FROM my_book_text WHERE chapter_id=5; amount := 24; -- 要读取的字符数 offset := 1; -- 起始位置 DBMS_LOB.READ(clob_var,amount,offset,output_var); --从CLOB数据中读取24个字符存储到 output_var 变量中 DBMS_OUTPUT.PUT_LINE(output_var); --显示读到的信息 END;
icode itemfile.itemcode%TYPE; emp_rec scott.emp%ROWTYPE;
关系运算符 |
说明 |
= |
比较两个变量是否相等,如果值相当,则返回 True |
<>, != |
比较两个变量,如果不相等,则返回 True |
< |
比较两个变量,检查值 1 是否小于值 2 |
> |
比较两个变量,检查值 1 是否大于 值 2 |
<= |
比较两个变量,检查变量 1 是否小于等于变量 2 |
>= |
比较两个变量,检查变量 1 是否大于等于变量 2 |
PL/SQL 支持的流程控制结构:
DECLARE icode VARCHAR2(4); irate NUMBER; BEGIN icode := ‘i203‘; SELECT itemrate INTO irate FROM itemfile WHERE itemcode = icode; IF irate > 200 THEN --条件判断 UPDATE itemfile SET itemrate = itemrate - 200 WHERE itemcode = icode; ELSE UPDATE itemfile SET itemrate = itemrate - 50 WHERE itemcode = icode; END IF; --结束 DBMS_OUTPUT.PUT_LINE(‘itemrate=‘|| irate); END;
BEGIN CASE ‘&grade’ WHEN ’A’ THEN DBMS_OUTPUT.PUT_LINE(’优异’); WHEN ’B’ THEN DBMS_OUTPUT.PUT_LINE (优秀’); WHEN ’C’ THEN DBMS_OUTPUT.PUT_LINE (’良好’); WHEN ’D’ THEN DBMS_OUTPUT.PUT_LINE (’一般’); WHEN ’F’ THEN DBMS_OUTPUT.PUT_LINE (’较差’); ELSE DBMS_OUTPUT.PUT_LINE (’没有此成绩’); END CASE; END;
LOOP sequence_of_statements END LOOP;
WHILE condition LOOP sequence_of_statements END LOOP;
FOR counter IN [REVERSE] value1..value2 LOOP sequence_of_statements END LOOP;
采用loop...exit...when...end loop循环控制的语法结构如下所示:
loop 循环体; exit when循环条件; end loop
这种循环控制的语法如下:
while 条件 loop 执行语句段; end loop;
循环例子:
--while循环 --循环输出Hello world declare var_i int := 10; begin loop dbms_output.put_line(‘Hello world‘); if var_i = 0 then exit; end if; var_i := var_i - 1; end loop; end; --loop输出1-10 declare var_i int := 1; begin loop dbms_output.put_line(‘i = ‘ || var_i); exit when var_i = 10; var_i := var_i + 1; end loop; End --while循环1-5 Declare var_i int:=1; Begin while var_i<=10 loop Dbms_output.put_line(‘I=‘||var_i); Var_i:=var_i+1; End loop; End; --for 循环 : for 变量 in 范围 loop --1-10输出 begin for i in 1..10 loop dbms_output.put_line(‘i = ‘ || i); end loop; end --对员工的工资判断,如果少于2000则加50,直到工资满足为止! declare var_sal int; begin loop select sal into var_sal from emp where empno = 7499; exit when var_sal >= 2000; update emp set sal = sal + 50 where empno = 7499; dbms_output.put_line(‘加50‘); end loop; end;
DECLARE qtyhand itemfile.qty_hand%type; relevel itemfile.re_level%type; BEGIN SELECT qty_hand,re_level INTO qtyhand,relevel FROM itemfile WHERE itemcode = ‘i201‘; IF qtyhand < relevel THEN GOTO updation; --跳转到<<updation>>语句块 ELSE GOTO quit; --跳转到<<quit>> END IF; <<updation>> UPDATE itemfile SET qty_hand = qty_hand + re_level WHERE itemcode = ‘i201‘; <<quit>> NULL; END;
EXECUTE IMMEDIATE dynamic_sql_string [INTO define_variable_list] [USING bind_argument_list];
例:
DECLARE sql_stmt VARCHAR2(200); emp_id NUMBER(4) := 7566; emp_rec emp%ROWTYPE; BEGIN EXECUTE IMMEDIATE ‘CREATE TABLE bonus1 (id NUMBER, amt NUMBER)‘; sql_stmt := ‘SELECT * FROM emp WHERE empno = :id‘; EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id; END;
--显示员工编号为7499的所有信息 declare Var_row emp%rowtype; begin select * into var_row from emp where empno = 7499; dbms_output.put_line(‘编号=‘ || var_row.empno || ‘姓名=‘ || var_row.ename); end;
--动态执行 declare var_row emp%rowtype; var_sql varchar(100); var_empno int; begin var_sql := ‘select * from emp where empno = :num‘ ; execute immediate var_sql into var_row using var_empno; dbms_output.put_line(‘编号=‘ || var_row.empno || ‘姓名=‘ || var_row.ename); end;
--用动态SQL来实现分页 begin execute immediate ‘select * from (select rownum rn, d.* from (select * from :tableName order by sal desc) d) where rn > :min and rn <= :max‘ using ‘emp‘ , 1, 5; End;
access_into_null --在未初化对象时出现 case_not_found --在CASE语句中的选项与用户输入的数据不匹配时出现 collection_is_null --在给尚未初始化的表或数组赋值时出现 cursor_already_open --在用户试图打开已经打开的游标时出现 dup_val_on_index --在用户试图将重复的值存在使用唯一索引的数据库列中时出现 invalid_cursor --在执行非法游标运算(如打开一个尚未打开的游标)时出现 invalid_number --在将字符串转换为数字时出现 login_denied --在输入的用户名或密码无效时出现 no_data_found --在表中不存在的请求的行时出现,此外,当程序引用已经删除的元素时 storage_error --在内存损坏或PL/SQL耗尽内存时出现 too_many_rows --在执行SELECT INTO语句后返回多行时出现 value_error --在产生大小限制错误时出现 zero_divide --以零作除数时出现 Others --针对所有异常
处理用户定义异常
DECLARE invalidCATEGORY EXCEPTION; category VARCHAR2(10); BEGIN category := ‘&Category‘; IF category NOT IN (‘附件‘,‘顶盖‘,‘备件‘) THEN RAISE invalidCATEGORY; ELSE DBMS_OUTPUT.PUT_LINE(‘您输入的类别是‘|| category); END IF; EXCEPTION WHEN invalidCATEGORY THEN DBMS_OUTPUT.PUT_LINE(‘无法识别该类别‘); END;
引发应用程序错误
DECLARE rate itemfile.itemrate%TYPE; rate_exception EXCEPTION; --定义异常 BEGIN SELECT NVL(itemrate,0) INTO rate FROM itemfile WHERE itemcode = ‘i207‘; IF rate = 0 THEN RAISE rate_exception; --引发异常 ELSE DBMS_OUTPUT.PUT_LINE(‘项费率为:‘ || rate); END IF; EXCEPTION WHEN rate_exception THEN --扑捉异常 RAISE_APPLICATION_ERROR(-20001, ‘未指定项费率‘); END;
引发系统级错误
begin if 10 > 5 then raise_application_error(-20001, ‘这个是自定义错误显示‘); end if; end;
标签:
原文地址:http://www.cnblogs.com/hopeblog/p/5003549.html