BEGIN IF 条件1 THEN 执行1; ELSIF 条件2 THEN 执行2; ELSE 执行3; END IF; --注意这里有分号 END;
--=========================================
DECLARE
ROW_COUNT NUMBER;
BEGIN
SELECT COUNT(1) INTO ROW_COUNT FROM teble_test;
IF ROW_COUNT >= 100 AND ROW_COUNT < 200 THEN DBMS_OUTPUT.PUT_LINE('大于100' || ROW_COUNT); ELSIF ROW_COUNT >= 200 AND ROW_COUNT < 300 THEN DBMS_OUTPUT.PUT_LINE('大于200'); ELSE DBMS_OUTPUT.PUT_LINE('count: ' || ROW_COUNT); END IF; END;
循环
do-while
1 2 3 4 5 6 7 8 9 10 11
DECLARE I NUMBER := 1; BEGIN LOOP
DBMS_OUTPUT.PUT_LINE(I); I := I + 1;
EXIT WHEN I > 10; END LOOP; END;
for
1 2 3 4 5 6 7 8 9 10 11
BEGIN FOR COUNTER IN 1 .. 5 LOOP DBMS_OUTPUT.PUT_LINE('for循环:' || COUNTER); END LOOP;
--反转 FOR COUNTER IN REVERSE 1 .. 5 LOOP DBMS_OUTPUT.PUT_LINE('for循环:' || COUNTER); END LOOP; END;
while
1 2 3 4 5 6 7 8 9
DECLARE I NUMBER(2); BEGIN I := 1; WHILE I < 5 LOOP DBMS_OUTPUT.PUT_LINE('while循环:' || I); I := I + 1; END LOOP; END;
--检索EMP表中的所有JOB为MANAGER的雇员信息 DECLARE /*声明游标、(游标输入参数变量为VAR_JOB)可选项*/ CURSOR CUR_EMP(VAR_JOB VARCHAR2:='SALESMAN') IS /*游标所使用的查询语句*/ SELECT EMPNO, ENAME, SAL FROM EMP WHERE JOB = VAR_JOB; /*声明一个RECORD类型的记录变量*/ TYPE RECORD_EMP IS RECORD( VAR_EMPNO EMP.EMPNO%TYPE, VAR_ENAME EMP.ENAME%TYPE, VAR_SAL EMP.SAL%TYPE);
EMP_ROW RECORD_EMP; BEGIN /*打开游标,指定输入参数值为MANAGER*/ OPEN CUR_EMP('MANAGER'); /*将游标指向结果集第一行数据并存入RECORD记录变量*/ FETCH CUR_EMP INTO EMP_ROW; /*如果游标有数据就循环*/ WHILE CUR_EMP%FOUND LOOP DBMS_OUTPUT.PUT_LINE('雇员编号:' || EMP_ROW.VAR_EMPNO || ' 雇员姓名:' || EMP_ROW.VAR_ENAME || ' 雇员薪水:' || EMP_ROW.VAR_SAL); /*将游标指向结果集下一条数据*/ FETCH CUR_EMP INTO EMP_ROW; END LOOP; /*关闭游标*/ CLOSE CUR_EMP; END; ------------------------------------------------------------------------- --另一种方式,使用%ROWTYPE类型 DECLARE CURSOR CUR_EMP IS /*使用FETCH+%ROWTYPE查询这里的查询字段必须和表中字段顺序及数量一致*/ SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO FROM EMP; /*定义一个%ROWTYPE接收变量*/ VAR_EMP_TYPE EMP%ROWTYPE; BEGIN OPEN CUR_EMP; FETCH CUR_EMP INTO VAR_EMP_TYPE; WHILE CUR_EMP%FOUND LOOP DBMS_OUTPUT.PUT_LINE('雇员编号:' || VAR_EMP_TYPE.EMPNO || ' 雇员姓名:' || VAR_EMP_TYPE.ENAME || ' 雇员薪水:' || VAR_EMP_TYPE.SAL); FETCH CUR_EMP INTO VAR_EMP_TYPE; END LOOP; CLOSE CUR_EMP; END; ------------------------------------------------------------------------- --使用do-while方式 ...... ..... OPEN cur_test; LOOP FETCH cur_test INTO V_MOBILE; EXIT WHEN cur_test%NOTFOUND; DBMS_OUTPUT.PUT_LINE(V_MOBILE); END LOOP; CLOSE cur_test; ------------------------------------------------------------------------- --for 无需手动打开关闭游标 DECLARE CURSOR EMP_CURSOR IS SELECT * FROM EMP; BEGIN /*使用for语句循环游标无需手动打开/关闭游标*/ FOR V_EMP_RECORD IN EMP_CURSOR LOOP DBMS_OUTPUT.PUT_LINE(V_EMP_RECORD.ENAME); END LOOP; END;
BEGIN UPDATE EMP SET SAL = SAL + 100 WHERE JOB = 'SALESMAN'; IF SQL%NOTFOUND THEN DBMS_OUTPUT.PUT_LINE('没有符合条件的雇员'); ELSE DBMS_OUTPUT.PUT_LINE('上调了:' || SQL%ROWCOUNT || '个雇员的工资'); END IF; END;
--弱类型 --将薪水低于3000的雇员薪水增加500,增加后最高不超过3000 DECLARE TYPE REF_CURSOR_TYPE IS REF CURSOR; --声明一个弱类型的动态游标类型 REF_CURSOR REF_CURSOR_TYPE; --定义一个游标为声明的弱类型游标 V_SAL EMP.SAL%TYPE;--声明一个变量用来接收雇员薪水 V_EMPNO EMP.EMPNO%TYPE;--声明一个变量用来接收雇员编号 BEGIN OPEN REF_CURSOR FOR SELECT SAL, EMPNO FROM EMP;--打开游标并指定使用的SQL语句 LOOP FETCH REF_CURSOR INTO V_SAL, V_EMPNO;--将游标指向一行数据并给变量赋值 EXIT WHEN REF_CURSOR%NOTFOUND;--当游标无数据时退出 IF V_SAL < 3000 THEN--薪水低于3000进入IF,这个IF最后会执行更新SQL IF V_SAL >= 2500 THEN--薪水低于3000又大于2500进入这个IF V_SAL := 3000; ELSE V_SAL := V_SAL + 500; END IF;--结束一个IF,一个IF对应一个END IF; UPDATE EMP SET SAL = V_SAL WHERE EMPNO = V_EMPNO;--更新雇员薪水 END IF;--结束最外层IF END LOOP;--结束LOOP循环 CLOSE REF_CURSOR;--关闭游标 END;
--强类型 --查询所有雇员姓名 DECLARE TYPE EMP_REF_CURSOR IS REF CURSOR RETURN EMP%ROWTYPE;--声明一个强类型(指定返回类型)的动态游标 REF_CURSOR EMP_REF_CURSOR;--定义一个声明的强类型游标 V_EMP_RECORD EMP%ROWTYPE;--定义一个接收变量 BEGIN OPEN REF_CURSOR FOR SELECT * FROM EMP; LOOP FETCH REF_CURSOR INTO V_EMP_RECORD; EXIT WHEN REF_CURSOR%NOTFOUND; DBMS_OUTPUT.PUT_LINE(V_EMP_RECORD.ENAME); END LOOP; CLOSE REF_CURSOR; END;
--删除 DROPPROCEDURE procedure_name; --编译 ALTER PROCEDURE procedure_name COMPILE
demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
CREATE OR REPLACE PROCEDURE PARA_PROCEDURE(PARA1 IN VARCHAR2(20), PARA2 OUT VARCHAR2(20)) IS DECLARE PARA3 VARCHAR2(20); BEGIN PARA3 := PARA1 || 'xxetryertyertyxx'; PARA2 := PARA3; END;
------------------------------------- DECLARE
PARA2 VARCHAR2(100);
BEGIN PARA_PROCEDURE('123', PARA2); DBMS_OUTPUT.PUT_LINE(PARA2); END;
--在存储过程中 CREATE OR REPLACE PROCEDURE trancPro IS BEGIN INSERT INTO tab1 VALUES('AA','1212','1313'); COMMIT; SAVEPOINT s1; INSERT INTO tab1 VALUES('BB','1414','1515'); DBMS_TRANSACTION.SAVEPOINT('s2'); UPDATE tab1 SET SNO='1515' WHERE ID='BB'; COMMIT; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN ROLLBACK TO SAVEPOINT s1; RAISE_APPLICATION_ERROR(-20010,'ERROR:违反唯一索引约束'); WHEN OTHERS THEN ROLLBACK; END trancPro;
异常
1 2 3 4 5 6 7
EXCEPTION WHEN exception_name THEN Code for handing exception_name [WHEN another_exception THEN Code for handing another_exception] [WHEN others THEN code for handing any other exception.]