Oracle PL/SQL进阶编程(第九弹:使用系统包:DBMS_JOB)

在Oracle开发中,经常需要对一些任务进行调度。在Oracle中,调度任务又称为作业,只要是使用DBMS_JOB包来实现的。

创建作业SUBMIT

这个过程用来创建一个作业,并且输出作业号码。当建立新的作业时,需要给出作业要执行的操作,作业在下一次运行的日期及运行的时间间隔,语法如下:

PROCEDURE SUBMIT(job       OUT BINARY_INTEGER,          -- 由过程自动生成的作业号,返回给调用方
                 What      IN VARCHAR2,                 -- 要执行的作业,通常是一个过程名
                 next_date IN DATE DEFAULT SYSDATE,     -- 下一次执行的日期
                 interval  IN VARCHAR2 DEFAULT NULL,    -- 执行周期的时间间隔
                 no_parse  IN BOOLEAN DEFAULT False,    -- 是否解析与作业相关的例程
                 instance  IN BINARY_INTEGER DEFAULT 0, -- 指定哪个例程可以运行作业
                 force     IN BOOLEAN DEFAULT False     -- 是否强制运行与作业相关的例程
                 );

举个例子,DBMS_DDL.ANALYZE_OBJECT可以分析数据表,并且将存储结果存储起来,对于SQL的运行效率有较大的提升,大多数DBA经常需要用到这个过程来进行性能优化,因此会将其定义为一个作业来每日运行一次,实现代码如下:

DECLARE
   v_jobno   NUMBER;
BEGIN
   DBMS_JOB.submit
        (v_jobno,                             --作业编号
          --作业执行的过程
         'DBMS_DDL.analyze_object(''TABLE'',''SCOTT'',''EMP'',''COMPUTE'');',
         --下一次执行的日期         
         SYSDATE,
         --执行的时间间隔,表示24小时。
         'SYSDATE+1'
        );  
   DBMS_OUTPUT.put_line('获取的作业编号为:'||v_jobno);  --输出作业编号
   COMMIT;
END;

在创建了作业后,可以通过user_jobs数据字典来查询创建的作业。

这里要说一下,interval参数是VARCHAR2类型,不是一个日期或天或分钟的数字,例如:
‘SYSDATE+1’:表示每天的当前时间运行
‘TRUNC(SYSDATE)+1’:表示每天的0点运行
‘TRUNC(SYSDATE)+17/24’:表示在每天下午5点运行
‘null’:表示作业立即运行,运行完退出,不重复运行

移除作业REMOVE

该过程用于移除在队列中的某个作业,当前运行的作业不受影响,即使删除的作业不再执行,依然会执行完毕,只是后续不会再次执行。用户只能删除属于自己的作业。
DBMS_JOB.REMOVE(job IN BINARY_INTEGER);
比如想删除作业22904,代码这样写:
EXECUTE DBMS_JOB.REMOVE(22904);

更改作业 CHANGE

CHANGEG用来改变已提交作业的一些设置的参数,语法如下:

DBMS_JOB.CHANGE(job       OUT BINARY_INTEGER,
                What      IN VARCHAR2,
                next_date IN DATE DEFAULT SYSDATE,
                interval  IN VARCHAR2 DEFAULT NULL,
                instance  IN BINARY_INTEGER DEFAULT 0,
                force     IN BOOLEAN DEFAULT False
                );

参数的含义与SUBMIT基本相同,如果参数what,next_date,interval为NULL,则保持以前的值不变。用户只能修改自己的作业。
比如想要把作业22904改为每两天执行一次,则:
DBMS_JOB.CHANGE(22904, NULL, NULL, 'SYSDATE + 2');

更改作业执行WHAT

用于改变指定作业执行的PL/SQL代码。
DBMS_JOB.WHAT(job IN BINARY_INTEGER, what IN VARCHAR2);

更改运行日期NEXT_DATE

DBMS_JOB.NEXT_DATE(job IN BINARY_INTEGER, next_date IN DATE);

数据库实例配置INSTANCE

该过程用于更改执行的数据库实例的配置。

DBMS_JOB.INSTANCE(job      IN BINARY_INTEGER,
                  instance IN BINARY_INTEGER,
                  force    IN BOOLEAN DEFAULT False);

instance为指定提交作业 到指定的数据库的实例。

更改间隔INTERVAL

DBMS_JOB.INTERVAL(job IN BINARY_INTEGER, interval IN VARCHAR2);

中断做业BROKEN

用于标记作业中断或非中断,中断作业将不再被执行,Oracle不会试图去执行一个标记为中断的作业,但是用户可以通过调用DBMS_JOB.RUN过程强制执行一个标记为中断的作业。

DBMS_JOB.BROKEN(job       IN BINARY_INTEGER,
                broken    IN BOOLEAN,
                next_date IN DATE DEFAULT SYSDATE);

比如要将作业22904标记为中断,并执行下一次的执行时间为下个星期一:
DBMS_JOB.BROKEN(22904, False, NEXT_DATE(SYSDATE, 'MONDAY'));

强制作业运行RUN

使用RUN可以强制作业立即执行,即使作业已标记为中断。因为作业在运行完后会计算下一次执行的时间,因此在调用RUN之后,下一次的执行时间也会发生改变。语法 如下:
DBMS_JOB.RUN(job IN BINARY_INTEGER, force IN BOOLEAN DEFAULT False);
force参数为True时,作业 执行优化配置无效,如果为False,则作业必须在指定的数据库实例中运行。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 OraclePL/SQL 编程,你可以创建一个函数来实现这个功能。首先,你需要声明一个函数,并定义一个参数,这个参数是部门号。然后,你可以使用 SELECT 语句来查询数据库该部门的员工信息,并将信息显示出来。 为了获取部门的最高工资,你可以使用一个循环结构,每次循环遍历一个员工的工资,并与当前的最高工资进行比较。如果当前员工的工资更高,就更新最高工资的值。 最后,你可以在函数的最后返回最高工资的值。 下面是一个简单的例子,它展示了如何使用 PL/SQL 编写一个函数: ``` CREATE OR REPLACE FUNCTION get_department_info (p_deptno NUMBER) RETURN NUMBER AS v_max_salary NUMBER; BEGIN -- 查询部门的员工信息 SELECT ename, job, sal, comm INTO v_max_salary FROM emp WHERE deptno = p_deptno; -- 遍历员工工资,更新最高工资 FOR i IN (SELECT sal FROM emp WHERE deptno = p_deptno) LOOP IF i.sal > v_max_salary THEN v_max_salary := i.sal; END IF; END LOOP; -- 返回最高工资 RETURN v_max_salary; END; ``` 这个函数接受一个参数 p_deptno,表示部门号。它返回一个数字,表示部门的最高工 ### 回答2: 编写一个PL/SQL函数,以部门号作为参数,显示该部门的雇员姓名、职位、工资、奖金,并返回部门最高工资。 ```sql CREATE OR REPLACE FUNCTION get_dept_info(p_deptno IN NUMBER) RETURN NUMBER IS v_max_salary NUMBER; BEGIN -- 声明变量存储最高工资 v_max_salary := 0; -- 使用游标查询部门的员工信息,括姓名、职位、工资、奖金 FOR emp IN (SELECT ename, job, sal, comm FROM emp WHERE deptno = p_deptno) LOOP -- 输出员工信息 DBMS_OUTPUT.PUT_LINE('姓名:'||emp.ename||',职位:'||emp.job|| ',工资:'||emp.sal||',奖金:'||emp.comm); -- 如果员工的工资大于最高工资,则更新最高工资 IF emp.sal > v_max_salary THEN v_max_salary := emp.sal; END IF; END LOOP; -- 返回部门最高工资 RETURN v_max_salary; END; / ``` 使用上述函数可以通过以下方式调用,并显示部门的员工信息和部门最高工资。 ```sql SET SERVEROUTPUT ON; DECLARE v_max_salary NUMBER; BEGIN v_max_salary := get_dept_info(10); -- 以部门号为10的参数调用函数 DBMS_OUTPUT.PUT_LINE('部门最高工资:'||v_max_salary); END; / ``` 上述函数和调用可以根据实际情况进行更改,确保表名、列名、参数和调用所需的正确性。 ### 回答3: 以下是用Oracle数据库PL/SQL编程基础编写的函数,它以部门号为参数,显示该部门的雇员姓名、职位、工资、奖金,并返回部门最高工资。 ``` CREATE OR REPLACE FUNCTION get_department_info(p_deptno NUMBER) RETURN NUMBER IS v_max_salary NUMBER := 0; BEGIN FOR emp_rec IN (SELECT e.ename, e.job, e.sal, e.comm FROM emp e WHERE e.deptno = p_deptno) LOOP dbms_output.put_line('雇员姓名: ' || emp_rec.ename || ', 职位: ' || emp_rec.job || ', 工资: ' || emp_rec.sal || ', 奖金: ' || emp_rec.comm); IF emp_rec.sal > v_max_salary THEN v_max_salary := emp_rec.sal; END IF; END LOOP; RETURN v_max_salary; END; / ``` 使用以上函数时,只需传入部门号作为参数即可: ``` SET SERVEROUTPUT ON DECLARE v_deptno NUMBER := 10; v_highest_salary NUMBER; BEGIN v_highest_salary := get_department_info(v_deptno); dbms_output.put_line('部门 ' || v_deptno || ' 的最高工资为: ' || v_highest_salary); END; / ``` 这个函数首先声明一个变量v_max_salary来保存最高工资,并初始化为0。然后使用循环遍历部门的雇员记录,根据部门号筛选雇员信息。在每次循环,输出雇员的姓名、职位、工资和奖金。同时,检查当前雇员的工资是否大于v_max_salary,如果是,则更新v_max_salary的值为当前工资。最后,返回v_max_salary作为函数的结果,并打印出部门的最高工资。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值