暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

AntDB 使用教程 / Oracle兼容 / SQL命令6

tocata 2024-08-19
30

CREATE PROCEDURE

名称

CREATE PROCEDURE —— 定义一个新的存储过程。执行此操作之前,要先设置将 PLSQL_MODE 打开,创建好存储过程后,再把此参数设置为 OFF,否则,事务不会自动提交,命令“/”可以提交事务。方法如下:

\set PLSQL_MODE ON

\set PLSQL_MODE OFF

概要

CREATE [ OR REPLACE ] PROCEDURE name

([argname [ IN | IN OUT | OUT ] argtype [ DEFAULT value ]

[, ...] ] )

{ IS | AS }

[ declaration; ] [, ...]

BEGIN

statement; [...]

[ EXCEPTION

{ WHEN exception [ OR exception ] [...] THEN

statement; [, ...] } [, ...]

]

END [ name ]

描述

CREATE PROCEDURE 命令定义一个新的存储过程。CREATE OR REPLACE PROCEDURE 命令既可以创建一个新的存储过程,也可以用新创建的存储过程定义替代已存在的存储过程定义。如果包含了模式的名称,那么存储过程是在指定模式下创建,否则就是在当前模式下创建。新的存储过程名不应与同一模式下任何存储过程的名称相同。除非打算使用 CREATE OR REPLACE PROCEDURE 命令更新一个已存在存储过程的定义。

创建存储过程的用户是新创建存储过程的所有者。

关于存储过程的更多内容参见章节 3。

参数

name

所创建存储过程的名称(可以采用模式限定的方式引用)。

argname

参数的名称。参数是通过在存储过程体内部的名称来引用的。

IN | IN OUT | OUT

参数模式。IN 将参数声明为输入参数。这是缺省的情况。IN OUT 允许参数既可以接收值,也可以返回值。 OUT 指定参数只是用作输出。

argtype

存储过程参数的数据类型。参数类型可以是基本数据类型,使用 %TYPE 作为数据类型的已存在列的拷贝,或者一个用户定义类型,比如嵌套表或者一个对象类型。对于任何基础数据类型来说,不应该指定长度-例如,指定 VARCHAR2,而不是 VARCHAR2(10)。

通过使用 tablename.columnname%TYPE,可以引用一个列的类型。当表的定义发生改变的时候,使用这种方式可以不用修改存储过程的主体。

DEFAULT value

当调用存储过程的时候没有为参数提供值时,它可以为输入参数提供一个缺省值。对于模式为 IN OUT 或者 OUT 的参数来说,不指定参数 DEFAULT。

DEFINER | CURRENT_USER

用来指定是否能使用存储过程所有者(DEFINER)或者当前执行存储过程的用户(CURRENT_USER)的权限来确定是否允许访问在存储过程中引用的数据库对象。在存储过程所有者(DEFINER)这种情况下,使用存储过程所有者的搜索路径来解析对非限定的数据库对象的引用。同时,在当前执行存储过程的用户(CURRENT_USER)这种情况下,使用当前正在执行存储过程用户的搜索路径来解析对非限定数据库对象的引用。DEFINER 是缺省选项。

declaration

变量,类型或者是 REF CURSOR 的声明。

statement

SPL 程序语句。需要注意的是一个 DECLARE-BEGIN-END 的代码块本身就被认为是一条 SPL 语句。因此,函数体内部可以包含嵌套代码块。

exception

异常条件的名称,例如 NO_DATA_FOUND,OTHERS 等等。

示例

下面这个存储过程列出了表 emp 中的雇员( emp 表格定义见【示例参考表格】):

\set PLSQL_MODE ON
CREATE OR REPLACE PROCEDURE list_emp()
IS
v_empno	NUMBER(4);
v_ename	VARCHAR2(10);
CURSOR emp_cur IS
SELECT empno, ename FROM emp ORDER BY empno;
BEGIN
OPEN emp_cur;
DBMS_OUTPUT.PUT_LINE('EMPNO	ENAME');
DBMS_OUTPUT.PUT_LINE('-----	-------');
LOOP
FETCH emp_cur INTO v_empno, v_ename;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empno || '	' || v_ename);
END LOOP;
CLOSE emp_cur;
END;
/
\set PLSQL_MODE OFF
SELECT list_emp();

NOTICE:  7369   SMITH
NOTICE:  7499   ALLEN
NOTICE:  7521   WARD
NOTICE:  7566   JONES
NOTICE:  7654   MARTIN
NOTICE:  7698   BLAKE
NOTICE:  7782   CLARK
NOTICE:  7788   SCOTT
NOTICE:  7839   KING
NOTICE:  7844   TURNER
NOTICE:  7876   ADAMS
NOTICE:  7900   JAMES
NOTICE:  7902   FORD
NOTICE:  7934   MILLER
 LIST_EMP 
----------
 
(1 row)
复制

下面这个存储过程首先根据雇员编号查询雇员编号,雇员姓名和工作种类,如果没有找到结果,那么使用雇员名称查询,最后使用 IN OUT 参数和 OUT 参数将结果返回。这个存储过程是在一个匿名代码块中调用的。

注意,下面的例子中,emp_job 的最后一个参数是输出,在 Oracle 中,可以通过 emp_job(v_empno,v_ename, v_job) 将结果直接赋给 v_job 变量。但是在 AntDB 中,调用存储过程的时候,结果变量不能放在参数中,只能通过这样的方式调用:re= emp_job(v_empno, v_ename);再从 re 中将结果提取出来( emp 表格定义见【示例参考表格】)。

\set PLSQL_MODE ON
CREATE OR REPLACE PROCEDURE emp_job (
p_empno	IN OUT numeric,
p_ename	IN OUT varchar2,
p_job	OUT	varchar2
)
IS
v_empno	emp.empno%TYPE; --函数参数不支持此种格式的定义
v_ename	emp.ename%TYPE;
v_job	emp.job%TYPE;
BEGIN
SELECT ename, job INTO v_ename, v_job FROM emp WHERE empno = p_empno;
p_ename := v_ename;
p_job	:= v_job;
DBMS_OUTPUT.PUT_LINE('Found employee # ' || p_empno);
EXCEPTION
WHEN NO_DATA_FOUND THEN
BEGIN
SELECT empno, job INTO v_empno, v_job FROM emp
WHERE ename = p_ename;
p_empno := v_empno;
p_job	:= v_job;
DBMS_OUTPUT.PUT_LINE('Found employee ' || p_ename);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Could not find an employee with ' ||
'number, ' || p_empno || ' nor name, '	|| p_ename);
p_empno := NULL;
p_ename := NULL;
p_job	:= NULL;
END;
END;
/

DECLARE
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_job   emp.job%TYPE;
re record;
BEGIN
v_empno := 7782;
v_ename := 'CLARK';
re := emp_job(v_empno, v_ename);
DBMS_OUTPUT.PUT_LINE('Employee No: ' || v_empno);
DBMS_OUTPUT.PUT_LINE('Name  : ' || v_ename);
DBMS_OUTPUT.PUT_LINE('Job   : ' || re.p_job);
END;
/
\set PLSQL_MODE OFF

Found employee CLARK
Employee No: 7782
Name	: CLARK
Job	: MANAGER
复制



「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论