过程(procedure)和函数(function):
过程和函数都以编译后的形式存放在数据库中,函数可以没有参数也可以有多个参数并有一个返回值。过程有零个或多个参数,没有返回值。函数和过程都可以通过参数列表接收或返回零个或多个值,函数和过程的主要区别不在于返回值,而在于他们的调用方式。过程是作为一个独立执行语句调用的:
创建过程的语法如下:
CREATE[ OR REPLACE] PROCEDURE [schema.] procedure_name
[arg1[in | out | in out] ........]
{AS|IS}
declaration_section
BEGIN
executable_section
[ EXCEPTION
exception_section ]
END [procedure_name]
IN 表示在调用过程的时候,实际参数的取值被传递给该过程,形式参数被认为是只读的,当过程结束时,控制会返回控制环境,实际参数的值不会改变。
OUT 在调用过程时实际参数的取值都将被忽略,在过程内部形式参数只能是被赋值,而不能从中读取数据,在过程结束后形式参数的内容将被赋予实际参数。
IN OUT 这种模式是IN和OUT的组合;在过程内部实际参数的值会传递给形式参数,形势参数的值可读也可写,过程结束后,形势参数的值将赋予实际参数
eg:
CREATE OR REPLACE PROCEDURE pro_hello(
p_name OUT s_emp.first_name%TYPE,
p_id IN s_emp.id%TYPE := 1)
AS
v_fname s_emp.first_name%TYPE;
BEGIN
--p_id := 10;
SELECT first_name
INTO p_name
FROM s_emp
WHERE id = p_id;
DBMS_OUTPUT.PUT_LINE('p_name: ' || p_name);
--p_name := v_fname;
--DBMS_OUTPUT.PUT_LINE('hello, ' || v_fname);
END;
函数:
CREATE [ OR REPLACE] FINCTION [schema.]function_name
[parameter_list]
RETURN returning_datatype
{AS|IS}
declaration_section
BEGIN
executable_section
[ EXCEPTION]
exception_section ]
END [procedure_name]
在执行部分函数必须有一个或多个return语句。
在创建函数中可以调用单行函数和组函数,例如:
CREATE OR REPLACE FUNCTION my_sin(DegreesIn IN NUMBER)
RETURN NUMBER
IS
pi NUMBER=ACOS(-1);
RadiansPerDegree NUMBER;
BEGIN
RadiansPerDegree=pi/180;
RETURN(SIN(DegreesIn*RadiansPerDegree));
END
eg:
CREATE OR REPLACE FUNCTION fun_getSalary(
p_id s_emp.id%TYPE,
p_mon NUMBER)
RETURN s_emp.salary%TYPE IS
v_base s_emp.salary%TYPE;
v_pct s_emp.commission_pct%TYPE;
v_saleAmt s_ord.total%TYPE;
v_sal s_emp.salary%TYPE;
BEGIN
SELECT salary, commission_pct
INTO v_base, v_pct
FROM s_emp
WHERE id = p_id;
IF v_pct IS NULL THEN
RETURN v_base;
END IF;
SELECT SUM(total)
INTO v_saleAmt
FROM s_ord
WHERE sales_rep_id = p_id
AND to_number(to_char(date_ordered,'mm')) = p_mon;
IF v_saleAmt IS NULL THEN
RETURN v_base;
END IF;
v_sal := v_base + v_saleAmt * (v_pct/100);
RETURN v_sal;
END;