当前位置:首页 » 编程语言 » oracle定时执行sql语句
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

oracle定时执行sql语句

发布时间: 2022-11-12 02:53:36

‘壹’ 如何让oracle数据库执行sql实时更新数据

什么意思?

你执行sql语句update等,可以实时更新数据(别忘记commit)

或者,你需要定时更新,那么需要考虑 jobs

‘贰’ 如何解析oracle执行计划

一、通过PL/SQL Dev工具
1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。
2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了,看到的结果和1中的一样,所以使用工具的时候推荐使用1方法。
注意:PL/SQL Dev工具的Command window中不支持set autotrance on的命令。还有使用工具方法查看计划看到的信息不全,有些时候我们需要sqlplus的支持。

二、通过sqlplus
1.最简单的办法
Sql> set autotrace on
Sql> select * from al;
执行完语句后,会显示explain plan 与 统计信息。
这个语句的优点就是它的缺点,这样在用该方法查看执行时间较长的sql语句时,需要等待该语句执行成功后,才返回执行计划,使优化的周期大大增长。如果不想执行语句而只是想得到执行计划可以采用:
Sql> set autotrace traceonly
这样,就只会列出执行计划,而不会真正的执行语句,大大减少了优化时间。虽然也列出了统计信息,但是因为没有执行语句,所以该统计信息没有用处,如果执行该语句时遇到错误,解决方法为:
(1)在要分析的用户下:
Sqlplus > @ ?
dbmsadminutlxplan.sql
(2) 用sys用户登陆
Sqlplus > @ ?sqlplusadminplustrce.sql
Sqlplus > grant plustrace to user_name;
- - user_name是上面所说的分析用户

2.用explain plan命令
(1) sqlplus > explain plan for select * from testdb.myuser
(2) sqlplus > select * from table(dbms_xplan.display);
上面这2种方法只能为在本会话中正在运行的语句产生执行计划,即我们需要已经知道了哪条语句运行的效率很差,我们是有目的只对这条SQL语句去优化。其实,在很多情况下,我们只会听一个客户抱怨说现在系统运行很慢,而我们不知道是哪个SQL引起的。此时有许多现成的语句可以找出耗费资源比较多的语句,如:
SELECT ADDRESS, substr(SQL_TEXT,1,20) Text, buffer_gets, executions,
buffer_gets/executions AVG FROM v$sqlarea
WHERE executions>0 AND buffer_gets > 100000 ORDER BY 5;
ADDRESS TEXT BUFFER_GETS EXECUTIONS AVG
-------- ---------------------------------------- ----------- ---------- ------------------------------------------------------------
66D83D64 select t.name, (sel 421531 60104 7.01336017
66D9E8AC select t.schema, t.n 1141739 2732 417.913250
66B82BCC select s.synonym_nam 441261 6 73543.5
从而对找出的语句进行进一步优化。当然我们还可以为一个正在运行的会话中运行的所有SQL语句生成执行计划,这需要对该会话进行跟踪,产生trace文件,然后对该文件用tkprof程序格式化一下,这种得到执行计划的方式很有用,因为它包含其它额外信息,如SQL语句执行的每个阶段(如Parse、Execute、Fetch)分别耗费的各个资源情况(如CPU、DISK、elapsed等)。

3、启用SQL_TRACE跟踪所有后台进程活动:
全局参数设置: .OracleHome/admin/SID/pfile中指定: SQL_TRACE = true (10g)
当前session中设置:
SQL> alter session set SQL_TRACE=true;
SQL> select * from al;
SQL> alter session set SQL_TRACE=false;
对其他用户进行跟踪设置:
SQL> select sid,serial#,username from v$session where username='XXX';
SID SERIAL# USERNAME
------ ---------- ------------------
127 31923 A
128 54521 B
开启跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,true);
关闭跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,false);
然后使用oracle自带的tkprof命令行工具格式化跟踪文件。

4、使用10046事件进行查询:
10046事件级别:
Lv1 - 启用标准的SQL_TRACE功能,等价于SQL_TRACE
Lv4 - Level 1 + 绑定值(bind values)
Lv8 - Level 1 + 等待事件跟踪
Lv12 - Level 1 + Level 4 + Level 8
全局设定:
OracleHome/admin/SID/pfile中指定: EVENT="10046 trace name context forever,level 12"
当前session设定:
开启:SQL> alter session set events '10046 trace name context forever, level 8';
关闭:SQL> alter session set events '10046 trace name context off';
对其他用户进行设置:
SQL> select sid,serial#,username from v$session where username='XXX';
SID SERIAL# USERNAME
------ ---------- ------------------
127 31923 A

SQL> exec dbms_system.set_ev(127,31923,10046,8,'A');

5、使用tkprof格式化跟踪文件: (根据下面SQL语句得到的文件都不存在该目录下,郁闷啊,懵懂啊...)

一般,一次跟踪可以分为以下几步:
1、界定需要跟踪的目标范围,并使用适当的命令启用所需跟踪。
2、经过一段时间后,停止跟踪。此时应该产生了一个跟踪结果文件。
3、找到跟踪文件,并对其进行格式化,然后阅读或分析。
--使用一下SQL找到当前session的跟踪文件:
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_namefrom( select p.spid from v$mystat m,v$session s, v$process pwhere m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,( select t.instance from v$thread t,v$parameter vwhere v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,( select value from v$parameter where name = 'user_mp_dest' ) d;-- 其它用户的 session SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_name from ( select p.spid from v$session s, v$process p where s.sid= '27' and s. SERIAL#= '30' and p.addr = s.paddr) p, ( select t.instance from v$thread t,v$parameter v where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i, ( select value from v$parameter where name = 'user_mp_dest' ) d;

--查找后使用tkprof命令,将TRACE文件格式为到D盘的explain_format.txt文件中
SQL> $tkprof d:/oracle/admin/FZLGFM/ump/fzlgfm_ora_3468.trc d:/explain_format.txt

文件内容大致如下(看不太懂....懵懂啊.....天啊....神啊.....过几时就懂了/////////////)
TKPROF: Release 9.2.0.1.0 - Proction on 星期二 4月 20 13:59:20 2010
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: d:/oracle/admin/FZLGFM/ump/fzlgfm_ora_3468.trc
Sort options: default
********************************************************************************
count = number of times OCI procere was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call********************************************************************************
alter session set events '10046 trace name context forever, level 8'

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.00 0 0 0 0

Misses in library cache ring parse: 0
Misses in library cache ring execute: 1
Optimizer goal: CHOOSE
Parsing user id: SYS

‘叁’ oracle 定时每天将查询的结果当作sql来执行

建立一个procere,procere中使用动态sql。
然后创建个job,就可以了。

‘肆’ oracle触发器中定时执行sql

1.
关于Oracle
触发器中定时执行SQL
的问题,
Oracle触
发器只是在表中数据被更新
如Insert,update,delete
等情况下才会触发,不能做到定时,只是能是有变化时才会执行!
2.
要做到定时执行可使用Job
来完成
3.
数据已经完成插入,建议插入数据时,直接使用触发器
4.
例2:限制对Departments表修改(包括INSERT,DELETE,UPDATE)的时间范围,即不允许在非工作时间修改departments表。
CREATE OR REPLACE TRIGGER tr_dept_time
BEFORE INSERT OR DELETE OR UPDATE
ON departments
BEGIN
IF (TO_CHAR(sysdate,'DAY') IN ('星期六', '星期日')) OR (TO_CHAR(sysdate, 'HH24:MI') NOT BETWEEN '08:30' AND '18:00') THEN
RAISE_APPLICATION_ERROR(-20001, '不是上班时间,不能修改departments表');
END IF;
END;

‘伍’ oracle触发器中定时执行sql

  1. 关于Oracle 触发器中定时执行SQL 的问题, Oracle触 发器只是在表中数据被更新 如Insert,update,delete 等情况下才会触发,不能做到定时,只是能是有变化时才会执行!

  2. 要做到定时执行可使用Job 来完成

  3. 数据已经完成插入,建议插入数据时,直接使用触发器

  4. 例2:限制对Departments表修改(包括INSERT,DELETE,UPDATE)的时间范围,即不允许在非工作时间修改departments表。

    CREATEORREPLACETRIGGERtr_dept_time
    BEFOREINSERTORDELETEORUPDATE
    ONdepartments
    BEGIN
    IF(TO_CHAR(sysdate,'DAY')IN('星期六','星期日'))OR(TO_CHAR(sysdate,'HH24:MI')NOTBETWEEN'08:30'AND'18:00')THEN
    RAISE_APPLICATION_ERROR(-20001,'不是上班时间,不能修改departments表');
    ENDIF;
    END;

‘陆’ Oracle怎么设置同时执行多条SQL语句

多个线程发过去,才能多条语句并发执行。单线程向OR服务器发SQL指令的话,就应该是按顺序进行,否则很多SQL的执行都会乱套,比如还没建立表就开始追加数据什么的。

也就是说,要并发执行SQL语句,请使用多个客户端向服务器发送SQL指令,或单个客户端中多线程向服务器发送SQL指令。也可以用定时事务来做到多个SQL并发执行。

‘柒’ 如何在oracle的PLSQL种定时删除一张表中三天前的数据

用SQL代码我不知道怎么来写,但是用程序知道。
写一个线程挂起,每到三天就执行SQL语句。SQL语句,删除三天前的数据就行了。直接在SQL里面让它定时删除这个可能搬不到吧。

‘捌’ 我想定时让 oracle 执行一段sql语句 怎么做

如:定时删除三分钟前的数据

###1.创建存储过程
SQL>createorreplaceprocerepro_delete_aas
2begin
3deletefromatwheret.a<(sysdate-3/1440);###一天1440分钟。即一分钟是1/1440
4end;
5/

Procerecreated
###2创建job
SQL>variablejob_pro_delete_anumber;
SQL>begin
2dbms_job.submit(:job_pro_delete_a,'pro_delete_a;',sysdate,'sysdate+3/1440');
3end;
4/

PL/
job_pro_delete_a
---------
127

###3.调用job
SQL>begin
2dbms_job.run(:job_pro_delete_a);
3end;
4/

PL/
job_pro_delete_a
---------
127

###4.删除job
SQL>begin
2dbms_job.remove(:job_pro_delete_a);
3end;
4/
Ps:select*fromuser_jobs;
dbms_job.remove(ID);

‘玖’ 求一个小脚本,每天让数据库(oracle)里的某一个元素(如num)增加1, 怎么实现

select (select (max(num)+1) from tb) into tb,做个定时器定时执行这句sql,或者触发器每次插入一条数据就执行这句sql。

‘拾’ Oracle中如何定时执行一条SQL语句

通过网上查询,找到一种方案,就是先在oracle里面对要定时的sql写成存储过程,再用DBMS_scheler对存储过程进行定时执行。

在数据库中新建了一个表MY_JOB_TEST

在数据库中新建了一个表MY_JOB_TEST

在数据库中新建了一个表MY_JOB_TEST

在PLSQL中,执行下面语句模拟存储过程的调用,执行后要点提交才有反应

[sql] view plain

  • BEGIN

  • INSERTINTOMY_JOB_TEST(NUM)VALUES(1);

  • END;


  • 然后下面建立一个存储过程JOB_TEST

    (注意,这里用户需要CREATE JOB权限,可以用超级管理员用户执行下面语句给指定用户赋予该权限)

    [sql] view plain

  • GrantCreateJobTo指定用户名



  • [sql] view plain

  • SQL>CREATEORREPLACEPROCEDURE

  • JOB_TEST

  • BEGIN

  • INSERTINTOMY_JOB_TEST(NUM)VALUES(1);

  • END;


  • (此处要执行存储过程不能用exec JB_TEST,这种执行方式只能在命令行中使用)
  • 使用DBMS_SCHEDULER进行定时,这里为每分钟执行一次

    [sql] view plain

  • SQL>BEGIN

  • DBMS_SCHEDULER.CREATE_JOB(

  • job_name=>'SCHEDULER_TEST',

  • job_type=>'STORED_PROCEDURE',

  • job_action=>'JOB_TEST',

  • start_date=>sysdate,

  • repeat_interval=>'FREQ=MINUTELY;INTERVAL=1');

  • END;


  • 但是这样子定时任务并不会执行。
  • 我们可以用下面的命令查看一下scheler的状态

    [plain] view plain

  • SQL>SELECT*FROMUSER_SCHEDULER_JOBS;

  • 此时我们可以看到enable的状态是false的,因此我们需要去启动定时任务
  • [plain] view plain

  • SQL>BEGIN

  • DBMS_SCHEDULER.ENABLE('SCHEDULER_TEST');


  • dbms_scheler.enable('j_test'); --启用jobs
    dbms_scheler.disable('j_test'); --禁用jobs
    dbms_scheler.run_job('j_test'); --执行jobs
    dbms_scheler.stop_job('j_test'); --停止jobs
    dbms_scheler.drop_job('j_test'); --删除jobs


    然后再查询job的enable装态,发现为true了。

    然后查看MY_JOB_TEST表,发现每分钟会往里面添加记录。

    当需要修改定时任务或者调度的其他属性时,可以用下面的

  • dbms_scheler.set_attribute('调度名','调度属性','调度值');



  • 至此,定时任务完成。