pl/sql编程学习笔记(二)

本文详细介绍Oracle数据库中的子程序(过程与函数)及其参数模式,包括IN、OUT和INOUT的区别与应用,并探讨包的概念、包规范与包体的定义、包的重载以及包的初始化功能。

针对上一篇的各种代码块,进行整合Oracle子程序分为两种:过程、函数


1 子程序

函数与过程实现上最大的区别就在于,函数是可以有返回值的,而过程只能依靠OUT 或者 INOUT来返回数据
过程
过程=过程的声明+PLSQL块

语法:
CREATE[OR REPLACE] PROCEDURE 过程名称([参数名称[参数模式]NOCOPY数据类型]) 
[AUTHID[DEFINER|CURENT_USER]]
AS|IS
	声明部分;
BEGIN
	程序部分
EXCEPTION 
	异常部分
END;
/
exec 过程名  --执行创建的过程
ps: 过程创建如果出现错误,使用show errors 显示错误详细信息, 重新编译子程序 ALTER PROCEDURE 过程名称 COMPILE ;

示例:
CREATE OR REPLACE PROCEDURE dept_insert_proc(
	p_dno dept.deptno%TYPE, 
	p_dna dept.dname%TYPE, 
	p_dlo dept.loc%TYPE)
AS
	v_deptCount	NUMBER ;		-- 保存COUNT()函数结果
BEGIN
	SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=p_dno ;	-- 统计
	IF v_deptCount > 0 THEN			-- 有此编号的部门
		RAISE_APPLICATION_ERROR(-20789,'增加失败:该部门已存在!') ;
	ELSE
		INSERT INTO dept(deptno,dname,loc) VALUES (p_dno,p_dna,p_dlo) ;
		DBMS_OUTPUT.put_line('新部门增加成功!') ;
		COMMIT ;
	END IF ;
EXCEPTION
	WHEN others THEN
		DBMS_OUTPUT.put_line('SQLERRM = ' || SQLERRM) ;
		ROLLBACK ;				-- 事务回滚
END ;
/
函数:

语法:
CREATE[OR REPLACE] FUNCTION 函数名称([参数名称[参数模式]NOCOPY数据类型]) 
[AUTHID[DEFINER|CURENT_USER]]
AS|IS
	声明部分;
BEGIN
	程序部分
EXCEPTION 
	异常部分
END;
/

示例:过程调用函数
CREATE OR REPLACE PROCEDURE invoke_proc
AS
	v_salary	NUMBER ;  --定义接收的变量
BEGIN 
	v_salary := get_salary_fun(7369) ; --调用自定义的函数  函数根据ID查询雇员信息
	DBMS_OUTPUT.put_line('雇员7369的工资为:' || v_salary) ;
END ;
/

查询过程对象SQL
SELECT object_name,created,timestamp,status 
FROM user_objects --数据字典 
WHERE object_type='PROCEDURE' OR object_type='FUNCTION';

查询子程序的相关源
SELECT * FROM user_source WHERE name='proc_name' ;  --查看过程
SELECT * FROM user_source WHERE name='func_name' ;  --查看函数


删除子程序
DROP PROCEDURE proc_name;
DROP FUNCTION func_name;

参数模式
IN(默认,数值传递):在子程序之中锁做的修改不会影响原始参数的内容;参数无法回传
OUT(空进带值出):不带任何数值到子程序之中,子程序可以通过此变量讲数值返回给调用处;
IN OUT(地址传递):可以将值到子程序之中,同事也会将子程序之中对变量的修改返回到调用处;

--定义一个过程
CREATE OR REPLACE PROCEDURE in_proc(
p_paramA IN VARCHAR2,-- 明确定义IN参数模式
p_paramB VARCHAR2-- 默认的参数模式为IN
AS
BEGIN
DBMS_OUTPUT.put_line('执行in_proc()过程:p_paramA = ' || p_paramA) ;
DBMS_OUTPUT.put_line('执行in_proc()过程:p_paramB = ' || p_paramB) ;
END ;
/
--顶一个PL/SQL块
DECLARE
v_titleA VARCHAR2(50) := 'Java开发实战经典';
v_titleB VARCHAR2(50) := 'Android开发实战经典' ;
BEGIN
in_proc(v_titleA , v_titleB) ;
END ;
/


--使用default设置默认值
CREATE OR REPLACE PROCEDURE in_proc(
p_paramA IN VARCHAR2 , 
p_paramB VARCHAR2 DEFAULT 'Oracle开发实战经典')-- 设置默认值
AS
BEGIN
DBMS_OUTPUT.put_line('执行in_proc()过程:p_paramA = ' || p_paramA) ;
DBMS_OUTPUT.put_line('执行in_proc()过程:p_paramB = ' || p_paramB) ;
END ;
/
--少传一个参数调用,默认设置起作用
DECLARE
v_titleAVARCHAR2(50) := 'Java开发实战经典';
BEGIN
in_proc(v_titleA ) ;
END ;
/

OUT参数模式
CREATE OR REPLACE PROCEDURE out_proc(
	p_paramA OUT VARCHAR2,		-- OUT参数模式
	p_paramB OUT VARCHAR2)		-- OUT参数模式
AS
BEGIN
	DBMS_OUTPUT.put_line('执行out_proc()过程:p_paramA = ' || p_paramA) ;
	DBMS_OUTPUT.put_line('执行out_proc()过程:p_paramB = ' || p_paramB) ;
	p_paramA := 'Java开发实战经典' ;	-- 此值将返回给实参
	p_paramB := 'Android开发实战经典' ;	-- 此值将返回给实参
END ;
/
DECLARE
	v_titleA	VARCHAR2(100) := '此处只是声明一个接收返回数据的标记';
	v_titleB	VARCHAR2(100) := '此内容不会传递到过程,但是过程会将修改内容传回' ;
BEGIN
	out_proc(v_titleA , v_titleB) ;
	DBMS_OUTPUT.put_line('调用out_proc()过程之后变量内容:v_titleA = ' || v_titleA) ;
	DBMS_OUTPUT.put_line('调用out_proc()过程之后变量内容:v_titleB = ' || v_titleB) ;
END ;
/

IN OUT参数模式 (Java中的引用传递)
CREATE OR REPLACE PROCEDURE inout_proc(
	p_paramA IN OUT VARCHAR2,	-- IN OUT参数模式
	p_paramB IN OUT VARCHAR2 )	-- IN OUT参数模式
AS
BEGIN
	DBMS_OUTPUT.put_line('执行inout_proc()过程:p_paramA = ' || p_paramA) ;
	DBMS_OUTPUT.put_line('执行inout_proc()过程:p_paramB = ' || p_paramB) ;
	p_paramA := 'Java开发实战经典' ;	-- 此值将返回给实参
	p_paramB := 'Android开发实战经典' ;	-- 此值将返回给实参
END ;
/
DECLARE
	v_titleA	VARCHAR2(50) := 'Java WEB开发实战经典';
	v_titleB	VARCHAR2(50) := 'Oracle开发实战经典' ;
BEGIN
	inout_proc(v_titleA , v_titleB) ;
	DBMS_OUTPUT.put_line('调用inout_proc()过程之后变量内容:v_titleA = ' || v_titleA) ;
	DBMS_OUTPUT.put_line('调用inout_proc()过程之后变量内容:v_titleB = ' || v_titleB) ;
END ;
/

返回嵌套表类型的
DECLARE
	TYPE emp_nested IS TABLE OF emp%ROWTYPE ;
	v_emp_return	emp_nested ;
	FUNCTION dept_emp_fun(p_dno emp.deptno%TYPE) RETURN emp_nested
	AS
		v_emp_temp	emp_nested ;
	BEGIN
		SELECT * BULK COLLECT INTO v_emp_temp FROM emp WHERE deptno=p_dno ;
		RETURN v_emp_temp ;
	END ;
BEGIN
	BEGIN
		v_emp_return := dept_emp_fun(10) ;
		FOR x IN v_emp_return.FIRST .. v_emp_return.LAST LOOP
			DBMS_OUTPUT.put_line('雇员编号:' || v_emp_return(x).empno || ',姓名:' || v_emp_return(x).ename || ',职位:' || v_emp_return(x).job) ;
		END LOOP ;
	EXCEPTION
		WHEN others THEN
			DBMS_OUTPUT.put_line('此部门没有雇员!') ;
	END ;
END ;
/

返回嵌套表类型
DECLARE
	v_sum	NUMBER ;
	FUNCTION add_fun(p_num NUMBER)
	RETURN NUMBER
	AS
	BEGIN
		IF p_num = 1 THEN
			RETURN 1 ;
		ELSE 
			RETURN p_num + add_fun(p_num - 1) ;
		END IF ;
	END ;
BEGIN
	v_sum := add_fun(100) ;		-- 进行1~100累加
	DBMS_OUTPUT.put_line('累加结果:' || v_sum) ;
END ; 
/

NOCOPY 将IN于OUT 由基于复制变成基于引用,若程序异常也可以执行下去
DECLARE
	TYPE dept_nested IS TABLE OF dept%ROWTYPE ;
	v_dept		dept_nested ;
	PROCEDURE useNocopy_proc(p_temp IN OUT NOCOPY dept_nested) 
	IS
	BEGIN
		-- 相关程序代码
	END ;
BEGIN
	SELECT * BULK COLLECT INTO v_dept FROM dept ;	-- 将雇员表全部数据拷贝到嵌套表之中
	v_dept.EXTEND(2000000,1) ;			-- 将集合扩充,数据以第1条记录为准进行填充
	useNocopy_proc(v_dept) ;				-- 使用NOCOPY
END ;
/
DECLARE
	v_varA	NUMBER := 10 ;
	v_varB	NUMBER := 20 ;
	PROCEDURE change_proc(
		p_paramINOUT IN OUT NUMBER , 
		p_paramNOCOPY IN OUT NOCOPY NUMBER) 
	IS
	BEGIN
		p_paramINOUT := 100 ;
		p_paramNOCOPY := 100 ;
		RAISE_APPLICATION_ERROR(-20001 , '测试NOCOPY.') ;
	END ;
BEGIN
	DBMS_OUTPUT.put_line('【过程调用之前】v_varA = ' || v_varA || ',v_varB = ' || v_varB) ;
	BEGIN
		change_proc(v_varA , v_varB) ;
	EXCEPTION
		WHEN OTHERS THEN
			DBMS_OUTPUT.put_line('SQLCODE = ' || SQLCODE || ',SQLERRM = ' || SQLERRM) ;
	END ;
	DBMS_OUTPUT.put_line('【过程调用之后】v_varA = ' || v_varA || ',v_varB = ' || v_varB) ;
END ;
/

自治事务
在ORACLE之中每一个SESSION都拥有独立的事务,而在一个事务处理过程之中都会执行一系列的SQL更新操作,这些都收到一个整体的事务控制,其他用户如果要进行操作则必须在执行commit或rollback之后才可以。但是如果现在开发的子程序之中需要进行独立的子事务处理,并且在此事务处理过程之中执行commit活rollback不影响整体主事务,那么久需要通过自治事务进行控制
DECLARE
	PROCEDURE dept_insert_proc AS
		PRAGMA AUTONOMOUS_TRANSACTION;		-- 自治事务
	BEGIN
		-- 此处更新将使用自治事务,主事务将被挂起
		INSERT INTO dept(deptno,dname,loc) VALUES (60,'cnn','南京') ;
		COMMIT ;								-- 提交自治事务
	END ;
BEGIN
	INSERT INTO dept(deptno,dname,loc) VALUES (50,'开发部','天津') ;
	dept_insert_proc() ;
	ROLLBACK ;									-- 此处为主事务回滚
END ;
/

过程函数授权
--GRANT EXECUTE ON c##scott.proc_name TO c##otheruser ;
CREATE OR REPLACE PROCEDURE proc_name
AUTHID CURRENT_USER AS --
BEGIN
	INSERT INTO func(ename,job,sal,comm) VALUES ('哈哈','程序员',11111,2222) ;
	COMMIT ;
END ;
/

使用JDBC调用存储过程
package cn.ys.demo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
public class ProcDemo {
	// 定义Oracle的数据库驱动程序 
	public static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver" ;
	// 定义Oracle数据库的连接地址
	public static final String DBURL = "jdbc:oracle:thin:@localhost:1521:orcl" ;
	// Oracle数据库的连接用户名
	public static final String DBUSER = "c##scott" ;
	// Oracle数据库的连接密码
	public static final String DBPASS = "tiger" ;
	public static void main(String[] args) throws Exception {
		Connection conn = null ;							// 数据库连接
		CallableStatement cstmt = null ;					// 数据库操作
		String sql = "{CALL proc_name(?,?,?)}" ;			// 调用过程
		Class.forName(DBDRIVER) ;							// 加载驱动程序
		// 连接MySQL数据库时,要写上连接的用户名和密码
		conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
		cstmt = conn.prepareCall(sql) ;						// 实例化对象
		cstmt.setInt(1, 70) ;								// 设置第一个参数是70
		cstmt.setInt(2, 80) ;								// 设置第一个参数是80
		cstmt.registerOutParameter(2, Types.INTEGER) ;		// 设置返回值类型
		cstmt.registerOutParameter(3, Types.INTEGER) ;		// 设置返回值类型
		cstmt.execute() ;									// 执行存储过程
		System.out.println("INOUT的返回值:" + cstmt.getInt(2));
		System.out.println("OUT的返回值:" + cstmt.getInt(3));
		cstmt.close() ;										// 操作关闭
		conn.close() ;										// 数据库关闭 
	}
}


2 包的概念

oracle中包的定义

包规范:定义包中可以被外部访问的部分,在包规范中声明的内容可以从应用程序和包的任何地方访问,其语法如下:
CREATE [OR REPLACE] PACKAGE 包名称
|AUTHID CURRENT_USER | DEFINER
IS|AS
	结构名称定义(类型,过程,函数,游标,异常等)
END[包名称];
/

包体:负责包规范中定义的函数或过程的具体代码实现,如果在包中定义了规范中没有的内容,则此部分被设为私有访问,包体语法如下:
CREATE [OR REPLACE] PACKAGE BODY 包名称
IS|AS
	结构实现(类型,过程,函数,游标,异常等)
BEGIN
<span style="white-space:pre">	</span>包初始化程序代码
END[包名称];
/

Demo:
--声明部分
CREATE OR REPLACE PACKAGE demo_pkg 
AS
	TYPE cursor_ref IS REF CURSOR ;
	FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN cursor_ref ;
END ;
/
--对声明的部分进行代码实现
CREATE OR REPLACE PACKAGE BODY demo_pkg
AS
	FUNCTION get_emp_fun(p_dno dept.deptno%TYPE) RETURN SYS_REFCURSOR
	AS
		cur_var		SYS_REFCURSOR ;
	BEGIN
		OPEN cur_var FOR SELECT * FROM emp WHERE deptno=p_dno ;	-- 打开参数游标
		RETURN cur_var ;
	END ;
END ;
/


包的重载
--编写包规范,同时进行子程序重载
CREATE OR REPLACE PACKAGE emp_delete_pkg
AS
	-- 删除雇员时所发生的异常
	emp_delete_exception	EXCEPTION ;
	-- 根据雇员编号删除雇员信息
	PROCEDURE delete_emp_proc(p_empno emp.empno%TYPE) ;
	-- 根据雇员姓名删除雇员信息
	PROCEDURE delete_emp_proc(p_ename emp.ename%TYPE) ;
	-- 根据雇员所在部门及职位删除雇员信息
	PROCEDURE delete_emp_proc(p_deptno emp.deptno%TYPE , p_job emp.job%TYPE) ;
END ;
/
CREATE OR REPLACE PACKAGE BODY emp_delete_pkg
AS
	-- 根据雇员编号删除雇员信息,如果没有数据被删除则抛出异常
	PROCEDURE delete_emp_proc(p_empno emp.empno%TYPE) AS
	BEGIN
		DELETE FROM emp WHERE empno=p_empno ;
		IF SQL%NOTFOUND THEN
			RAISE emp_delete_exception ; --抛出异常
		END IF ;
	END delete_emp_proc ;
	-- 根据雇员姓名删除雇员信息,如果没有数据被删除则抛出异常
	PROCEDURE delete_emp_proc(p_ename emp.ename%TYPE) AS
	BEGIN
		DELETE FROM emp WHERE ename=UPPER(p_ename) ;
		IF SQL%NOTFOUND THEN
			RAISE emp_delete_exception ;
		END IF ;
	END delete_emp_proc ;
	-- 根据部门编号和雇员职位删除雇员信息,如果没有数据被删除则抛出异常
	PROCEDURE delete_emp_proc(p_deptno emp.deptno%TYPE , p_job emp.job%TYPE) AS
	BEGIN
		DELETE FROM emp WHERE deptno=p_deptno AND job=p_job ;
		IF SQL%NOTFOUND THEN
			RAISE emp_delete_exception ;
		END IF ;
	END delete_emp_proc ;
END ;
/

包的初始化功能:
--定义包规范
CREATE OR REPLACE PACKAGE init_pkg AS
	-- 定义索引表类型,里面将保存多个dept行记录,使用数字作为索引类型
	TYPE dept_index IS TABLE OF dept%ROWTYPE INDEX BY PLS_INTEGER ;
	-- 定义要操作的游标
	CURSOR dept_cur RETURN dept%ROWTYPE ;
	-- 定义索引表变量
	v_dept	dept_index ;
	-- 定义部门增加操作函数,如果增加成功返回true,否则返回false
	FUNCTION dept_insert_fun(p_deptno dept.deptno%TYPE , p_dname dept.dname%TYPE , p_loc dept.loc%TYPE) RETURN BOOLEAN ;
END ;
/
--实现定义的包规范
CREATE OR REPLACE PACKAGE BODY init_pkg AS
	CURSOR dept_cur RETURN dept%ROWTYPE IS 
		SELECT * FROM dept ;
	FUNCTION dept_insert_fun(p_deptno dept.deptno%TYPE , p_dname dept.dname%TYPE , p_loc dept.loc%TYPE) RETURN BOOLEAN AS
	BEGIN
		IF NOT v_dept.EXISTS(p_deptno) THEN	-- 数据不存在
			INSERT INTO dept(deptno,dname,loc) VALUES (p_deptno,p_dname,p_loc) ;
			v_dept(p_deptno).deptno := p_deptno ;
			v_dept(p_deptno).dname := p_dname ;
			v_dept(p_deptno).loc := p_loc ;
			RETURN true ;
		ELSE
			RETURN false ;
		END IF ;
	END dept_insert_fun ;
BEGIN
	-- 包初始化操作:将游标中的数据保存到索引表之中,同时以部门编号作为索引表操作索引
	FOR dept_row IN dept_cur LOOP
		v_dept(dept_row.deptno) := dept_row ;
	END LOOP ;
EXCEPTION
	WHEN OTHERS THEN
		DBMS_OUTPUT.put_line('程序出现错误。') ;
END ;
/

包引用纯度级别:

CREATE OR REPLACE PACKAGE purity_pkg AS
	-- 定义包中的变量
	v_name VARCHAR2(10) := 'cnn' ;
	-- 根据雇员编号删除雇员信息。但此函数不能执行更新操作
	FUNCTION emp_delete_fun_wnds(p_empno emp.empno%TYPE) RETURN NUMBER ;
	-- 根据雇员编号查找雇员信息。但此函数不能执行SELECT操作
	FUNCTION emp_find_fun_rnds(p_empno emp.empno%TYPE) RETURN NUMBER ;
	-- 使用新的内容修改v_name变量内容。但此函数不能修改包中的变量
	FUNCTION change_name_fun_wnps(p_param VARCHAR2) RETURN VARCHAR2 ;
	-- 读取v_name属性内容。但此函数不能读取包中变量
	FUNCTION get_name_fun_rnps(p_param NUMBER) RETURN VARCHAR2 ;	
	PRAGMA RESTRICT_REFERENCES(emp_delete_fun_wnds, WNDS) ;		-- 设置函数纯度级别,不能执行更新操作
	PRAGMA RESTRICT_REFERENCES(emp_find_fun_rnds, RNDS) ;		-- 设置函数纯度级别,不能执行SELECT操作
	PRAGMA RESTRICT_REFERENCES(change_name_fun_wnps, WNPS) ;	-- 设置函数纯度级别,不能修改包中的变量
	PRAGMA RESTRICT_REFERENCES(get_name_fun_rnps, RNPS) ;		-- 设置函数纯度级别,不能读取包中变量
END ;
/
--定义执行包,违反函数纯度规则
CREATE OR REPLACE PACKAGE BODY purity_pkg AS
	-- 根据雇员编号删除雇员信息。但此函数不能执行更新操作
	FUNCTION emp_delete_fun_wnds(p_empno emp.empno%TYPE) RETURN NUMBER AS
	BEGIN	-- 此函数由于定义了wnds纯度,所以无法执行数据表更新操作
		DELETE FROM emp WHERE empno=p_empno ;
		RETURN 0 ;	-- 满足函数要求返回数据
	END ;
	-- 根据雇员编号查找雇员信息。但此函数不能执行SELECT操作
	FUNCTION emp_find_fun_rnds(p_empno emp.empno%TYPE) RETURN NUMBER AS
		v_emp	emp%ROWTYPE ;
	BEGIN	-- 此函数由于定义了rnds纯度,所以无法执行数据表查询操作
		SELECT * INTO v_emp FROM emp WHERE empno=p_empno ;
		RETURN 0 ;	-- 满足函数要求返回数据
	END ;
	-- 使用新的内容修改v_name变量内容。但此函数不能修改包中的变量
	FUNCTION change_name_fun_wnps(p_param VARCHAR2) RETURN VARCHAR2 AS 
	BEGIN	-- 此函数由于定义了wnps纯度,所以函数无法修改包中的v_name变量
		v_name := p_param ;
		RETURN '' ;	-- 满足函数要求返回数据
	END ;
	-- 读取v_name属性内容。但此函数不能读取包中变量
	FUNCTION get_name_fun_rnps(p_param NUMBER) RETURN VARCHAR2 AS 
	BEGIN	-- 此函数由于定义了rnps,所以函数无法读取v_name变量
		RETURN v_name ;
	END ;
END ;
/

3 系统工具包

DBMS_OUTPUT包
DECLARE
	v_line1		VARCHAR2(200) ;			-- 保存第1行数据
	v_status	NUMBER ;			-- 保存状态
BEGIN
	DBMS_OUTPUT.enable ;		-- 启用缓冲
	DBMS_OUTPUT.put_line('此信息可以正常输出。') ;
	--DBMS_OUTPUT.disable ;		-- 禁用缓冲
	--DBMS_OUTPUT.put_line('此信息输出无法显示。') ;
	DBMS_OUTPUT.put('www.') ;	--向缓冲区输入内容
	DBMS_OUTPUT.put('www1.') ;	--向缓冲区输入内容
	DBMS_OUTPUT.new_line ;		-- 换行,输出之前缓冲区内容
	DBMS_OUTPUT.put('www2.') ;	--向缓冲区输入内容
	DBMS_OUTPUT.get_line(v_line1 , v_status) ;	-- 读取缓冲区一行数据
END ;
/

DBMS_JOB包
DROP SEQUENCE job_seq ;				--删除序列
DROP TABLE job_data PURGE ;			--删除表,不允许恢复
CREATE SEQUENCE job_seq ;			--创建序列
CREATE TABLE job_data (				--创建表
	jid		NUMBER ,
	title		VARCHAR2(20) ,
	job_date	DATE ,
	CONSTRAINT pk_jid PRIMARY KEY(jid)
) ;

--定义过程,实现数据插入
CREATE OR REPLACE PROCEDURE insert_demo_proc(p_title job_data.title%TYPE) AS
BEGIN
	INSERT INTO job_data(jid,title,job_date) VALUES (job_seq.nextval ,p_title, SYSDATE) ;
END ;
/
--定义一个job
DECLARE
	v_jobno		NUMBER ;
BEGIN
	DBMS_JOB.submit(v_jobno ,			-- 通过OUT模式返回创建的作业编号
		'insert_demo_proc(''作业A'') ;' , 		-- 作业执行时需要调用的过程
		SYSDATE ,					-- 作业开始时间
		'SYSDATE + (1/(24*60*60))') ;		-- 作业操作间隔
	DBMS_OUTPUT.put_line('作业编号:' || v_jobno) ;
	COMMIT ; 						-- 必须执行此操作
END ;
/
--修改JOB_QUEUE_PROCESSES参数
ALTER SYSTEM SET JOB_QUEUE_PROCESSES =10 ;
--查询user_jobs数据字典
select job,next_date,broken,interval,what from user_jobs ;
--修改作业的运行间隔,每小时间隔一次
EXECUTE DBMS_JOB.interval(v_jobno , 'SYSDATE + (1/(24*60))') ;  --v_jobon为返回的作业编号
--删除作业
EXECUTE DBMS_JOB.remove(v_jobno) ;



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值