job
DECLARE
job BINARY_INTEGER;
begin
sys.dbms_job.submit(job,
'CUX_RPT_MATERIEL_MONTH_PKG.RPT_MATERIEL_SPEND_MONTH_ALL(date''2013-06-28'');', --过程名
to_date('13-09-2014 16:13:59', 'dd-mm-yyyy hh24:mi:ss'), --执行时间 sysdate当前执行
trunc(add_months(SYSDATE,1)) + 3/24); --下次执行时间,如果为null表示只执行一次
commit;
end;
schedule
declare
v_n number default 0;
ind number default 0;
BEGIN
select count(*) into v_n
from user_scheduler_jobs
where job_action = '过程名';
if v_n > 0 then
DBMS_SCHEDULER.drop_job('PRO_MONTH_REPORT_ALL_JOBS');
end if;
dbms_scheduler.create_job('PRO_MONTH_REPORT_ALL_JOBS',
job_type => 'STORED_PROCEDURE',
job_action => '过程名',
number_of_arguments => 0,
start_date => sysdate,
repeat_interval => 'Freq=Monthly;ByMonthDay=28;ByHour=0;ByMinute=0;BySecond=0',
end_date => NULL,
job_class => 'DEFAULT_JOB_CLASS',
enabled => FALSE,
auto_drop => FALSE,
comments => '描述');
dbms_scheduler.enable('PRO_MONTH_REPORT_ALL_JOBS');
COMMIT;
END;
select ... from <TableName>
where <Conditional-1>
start with <Conditional-2>
connect by [prior] <Conditional-3>;如果connect by prior中的prior被省略,则查询将不进行深层递归。
<Conditional-1>:过滤条件,用于对返回的所有记录进行过滤。
<Conditional-2>:查询结果重起始根结点的限定条件。
<Conditional-3>:连接条件
http://www.2cto.com/database/201108/101766.html
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FOR select_statement
[ FOR UPDATE [ OF column_name [ ,...n ] ] ]
[;]
SELECT B.OWNER, B.OBJECT_NAME, A.SESSION_ID, A.LOCKED_MODE
FROM V$LOCKED_OBJECT A, DBA_OBJECTS B
WHERE B.OBJECT_ID = A.OBJECT_ID;
锁表与原因
select l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
s.user#,
l.os_user_name,
s.machine,
s.terminal,
a.sql_text,
a.action
from v$sqlarea a, v$session s, v$locked_object l
where l.session_id = s.sid
and s.prev_sql_addr = a.address
order by sid, s.serial#;
CREATE SEQUENCE EPSE_MATERIAL_MASTER_DATA_SEQ
INCREMENT BY 1 -- 每次加几个
START WITH 1000 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
CACHE 10;
CREATE SEQUENCE BD_WARE_FORECAST_SEQ
INCREMENT BY 1 -- 每次加几个
START WITH 1 -- 从1开始计数
MAXVALUE 99999 -- 最大值99999
CYCLE -- 循环
CACHE 10;
--实例1
--创建一个表的类型 定义一个 VARCHAR2(100)单值类型
CREATE OR REPLACE TYPE t_defind_type IS TABLE OF VARCHAR2(100);
DECLARE
rids t_defind_type := t_defind_type();--声明引用表类型
BEGIN
SELECT dsc.root_id BULK COLLECT
INTO rids FROM bbbb dsc ;
--输出单个值
FOR rid IN (SELECT COLUMN_VALUE AS pid FROM table(rids)) LOOP
dbms_output.put_line(rid.pid);
END LOOP;
END;
--实例2
--创建一个表的类型指定类型为对象类型
create or replace type type_row as object
(
id int,
name varchar2(50)
);
create or replace type type_table is table of type_row;
--管道方式
CREATE OR REPLACE FUNCTION F_PIPE(S NUMBER) RETURN TYPE_TABLE
PIPELINED AS
V_TYPE_ROW TYPE_ROW;
BEGIN
FOR I IN 1 .. S LOOP
V_TYPE_ROW := TYPE_ROW(I, 'name'||TO_CHAR(I * I));
PIPE ROW(V_TYPE_ROW);
END LOOP;
RETURN;
END F_PIPE;
--普通方式
CREATE OR REPLACE FUNCTION F_NORMAL(S NUMBER) RETURN TYPE_TABLE AS
RS TYPE_TABLE := TYPE_TABLE();
BEGIN
FOR I IN 1 .. S LOOP
RS.EXTEND;
RS(RS.COUNT) := TYPE_ROW(RS.COUNT, 'name' || TO_CHAR(RS.COUNT));
/* RESULT(RESULT.COUNT) := TYPE_ROW(NULL, NULL);
RS(RS.COUNT).NAME := RS(RS.COUNT).NAME || 'xxxx';*/
END LOOP;
RETURN RS;
END F_NORMAL;
SELECT id,NAME from table(F_NORMAL(10000));--在返回的集合上有局限性(回报进程内存不足)
SELECT id,NAME from table(f_pipe(10000000));
SELECT * FROM User_Source t WHERE
upper(t.TEXT) LIKE '%关键字%';
--8、创建db_link
CREATE DATABASE LINK mydblink20141024
CONNECT TO eps_50_test IDENTIFIED BY eps_50_test
USING '(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.0.14.220)(PORT = 1521)))
(CONNECT_DATA = (SERVICE_NAME = mixdb98)
)
)';
大数据批量查询【BULK COLLECT】oracle 关键字将数据放在临时表类型中,这样就可以一次性从硬盘中读取到所有的信息集,避免多次读取硬盘信息。注意:数据量过大采用limit限定之后循环读取。
大数据插入、查询、删除【FORALL】关键字进行操作,可以避免多次上下文切换。
如果存在只要数据源不需表的情况可以采用管道函数【pipelined】,获取一个Collections,然后操作这个集合来处理正常的业务,可以有效的提高效率
例子:
--A、创建一个表的类型
CREATE OR REPLACE TYPE t_vc IS TABLE OF VARCHAR2(100);
--实例
DECLARE
empIds t_vc := t_vc();--声明引用表类型
BEGIN
SELECT dsc.employee_id BULK COLLECT
INTO empIds FROM dc_sys_employee dsc WHERE dsc.person_status = '01'
AND dsc.company_id IN (SELECT GUID FROM dc_sys_company_info t WHERE t.status = 'Y' START WITH t.guid = '755YS'
CONNECT BY PRIOR t.guid = t.p_company_id);
--输出单个值
dbms_output.put_line(empIds(1));
--引用表类型查询数据进行删除
delete ware_wit_plan t WHERE t.employee_id IN (SELECT COLUMN_VALUE FROM table(empIds)) AND t.source='在职' and t.status='NA' AND t.is_delete = 'N';
COMMIT ;
END;
--B
DECLARE
TYPE NumList IS VARRAY(20) OF NUMBER;
depts NumList := NumList(10, 30, 70); -- department numbers
BEGIN
FORALL i IN depts.FIRST..depts.LAST
DELETE FROM employees_temp WHERE department_id = depts(i);
COMMIT;
END;
/
A、UNION,UNION ALL,INTERSECT,MINUS的区别
Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;Intersect,对两个结果集进行交集操作,不包括重复行,同时进行默认规则的排序;Minus,对两个结果集进行差操作,不包括重复行,同时进行默认规则的排序。
intersect运算返回查询结果中相同的部分
--查询临时表空间及大写
SELECT NAME, BYTES / 1024 / 1024 AS "大小(M)"
FROM V$TEMPFILE
ORDER BY BYTES;
--查询默认临时表空间
SELECT *
FROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME = 'DEFAULT_TEMP_TABLESPACE';
--创建temp02临时表空间
CREATE TEMPORARY TABLESPACE TEMP02 TEMPFILE 'D:\ORACLE\ORADATA\TFJS\TEMP01.DBF' SIZE 1000M AUTOEXTEND ON;
--修改默认临时表空间temp02
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE TEMP02;
--删除temp临时表空间
DROP TABLESPACE TEMP INCLUDING CONTENTS AND DATAFILES;
--创建temp临时表空间
CREATE TEMPORARY TABLESPACE TEMP TEMPFILE 'TEMP01.DBF' SIZE 4000M REUSE AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED
--修改默认临时表空间temp
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE TEMP;
--删除temp02临时表空间
DROP TABLESPACE TEMP02 INCLUDING CONTENTS AND DATAFILES;
--查询剩余表空间
SELECT TABLESPACE_NAME, FREE_SPACE / 1024 / 1024 AS "FREE SPACE(M)"
FROM DBA_TEMP_FREE_SPACE
WHERE TABLESPACE_NAME = 'TEMP';
*表分区的几种类型及操作方法
一.范围分区:
四.组合范围散列分区
这种分区是基于范围分区和列表分区,表首先按某列进行范围分区,然后再按某列进行列表分区,分区之中的分区被称为子分区。
create or replace trigger inv_dtl_tmp_after_insert
before insert on inv_dtl_tmp
for each row
begin
if inserting then
if :NEW.zictag IS NOT NULL then
select substr(:NEW.zictag,0,1) into :NEW.zictag from dual;
ELSE
:NEW.zictag:='1';
end if;
end if;
end;
过程 例子
主过程
create or replace procedure WX_MATERIAL_INFORM IS
num NUMBER;
str varchar2(300);
BEGIN
FOR c IN (SELECT orderid, creat_time, employee_id, employee_name, div_code, div_name, company_id, company_name, brach_id, brach_name, status, origin, last_update_time, update_own, remark, end_time, guid, msg_status FROM int_material_inform WHERE msg_status = '0')
LOOP
INSERT INTO his_int_material_inform
(orderid, creat_time, employee_id, employee_name, div_code, div_name, company_id, company_name, brach_id, brach_name, status, origin, last_update_time, update_own, remark, end_time, guid, msg_status)
VALUES
(c.orderid, c.creat_time, c.employee_id, c.employee_name, c.div_code, c.div_name, c.company_id, c.company_name, c.brach_id, c.brach_name, c.status, c.origin, c.last_update_time, c.update_own, c.remark, c.end_time, c.guid, c.msg_status);
END LOOP;
--DELETE FROM int_material_inform WHERE msg_status = '0';
COMMIT;
BEGIN
WX_TEST(SYSDATE);
COMMIT ;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('TOO_MANY_ROWS');
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('NOT_DATA_FOUND');
ROLLBACK;--回滚防止WX_TEST锁表
WHEN OTHERS THEN
BEGIN
SELECT COUNT(1) INTO num FROM USER_TABLES WHERE TABLE_NAME = UPPER('BBBB_1') ;
IF num > 0 THEN
EXECUTE IMMEDIATE 'DROP TABLE BBBB_1' ;
dbms_output.put_line('DROP TABLE BBBB_1');
END IF;
str := 'CREATE TABLE BBBB_1 AS SELECT * FROM BBBB';--过程中加入DDL语句
EXECUTE IMMEDIATE str;--立即执行
END;
dbms_output.put_line(SQLERRM);
dbms_output.put_line(SQLCODE);
dbms_output.put_line('出现异常备份数据');
END;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK ;
dbms_output.put_line(SQLERRM);
dbms_output.put_line(SQLCODE);
/* set_pro_log('his_int_material_inform',
'微信通知迁移失败:' || sqlerrm,
sysdate,
'');*/
end WX_MATERIAL_INFORM;
被调用过程
--参数 分为in out inout 默认为in
CREATE OR REPLACE PROCEDURE WX_TEST(IDATE DATE, RESULT_TEXT OUT VARCHAR2) IS
IDX VARCHAR2(10);
I_DATE DATE;
CURSOR CURSOR_1 IS
SELECT B.LANGUAGE FROM B;
MYREC B%ROWTYPE;
CURSOR CURSOR_2(I VARCHAR2) IS
SELECT B.LANGUAGE FROM B WHERE B.LANGUAGE = I;
MYCOL B.LANGUAGE%TYPE;
BEGIN
I_DATE := IDATE;
DBMS_OUTPUT.PUT_LINE('记录日志1' || I_DATE);
OPEN CURSOR_1;
FETCH CURSOR_1
INTO MYREC;
WHILE CURSOR_1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE('sdfs' || MYREC.LANGUAGE);
FETCH CURSOR_1
INTO MYREC;
END LOOP;
CLOSE CURSOR_1;
OPEN CURSOR_2('US');
LOOP
FETCH CURSOR_2
INTO MYCOL;
EXIT WHEN CURSOR_2%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(MYCOL);
END LOOP;
CLOSE CURSOR_2;
-- dbms_output.put_line(SQLCODE);
SELECT B.ID INTO IDX FROM BBBB B WHERE B.ID = '0' FOR UPDATE NOWAIT; --对表上锁
--DELETE FROM int_material_inform WHERE msg_status = '0';
-- error_number_in 之容许从 -20000 到 -20999 之间,
-- 这样就不会与 ORACLE 的任何错误代码发生冲突。error_msg_in 的长度不能超过 2k,否则截取 2k
IF IDX = 0 THEN
RESULT_TEXT := IDX;
RAISE_APPLICATION_ERROR(-20001, '数值不能为0');
END IF;
/* EXCEPTION
WHEN OTHERS THEN
ROLLBACK ;
dbms_output.put_line(SQLERRM);
dbms_output.put_line(SQLCODE);
\* set_pro_log('his_int_material_inform',
'微信通知迁移失败:' || sqlerrm,
sysdate,
'');*\*/
END WX_TEST;
--listagg函数与wm_concat函数
SELECT listagg(zicplnnum,',') WITHIN GROUP (ORDER BY zicplnnum),wm_concat(zicplnnum) FROM inventory_plans_details;
--树结构,SYS_CONNECT_BY_PATH函数用于显示节点路径;SIBLINGS对树的分支进行排序
--注意:如果要先过滤再进行树形查询,则要用子查询
SELECT T.GUID,T.P_COMPANY_ID,T.COMPANY_NAME,SYS_CONNECT_BY_PATH(T.COMPANY_NAME,',') 路径
FROM dc_sys_company_info t START WITH t.guid = 'B025Y'
CONNECT BY (PRIOR T.GUID) = T.P_COMPANY_ID
ORDER SIBLINGS BY T.GUID DESC;
--函数coalesce相对于nvl要好用,可以接受多个列,返回第一个不为null的值
--随机排序函数order by dbms_random.value()
--定义转义语句后面加ESCAPE 如:ESCAPE'\'
--关键字“WITH CHECK OPTION”限制数据的录入或者ALTER TABLE V_TABLE ADD CONSTRAINTS V_COL CHECK(COL >10)
INSERT INTO (SELECT CRDATE FROM inventory_plans t
WHERE t.CRDATE < SYSDATE WITH CHECK OPTION)
VALUES(SYSDATE);
--多表插入用无条件insert、insert all(加条件)、insert first(第一个表满足条件插入、第二个表就不用插入了)
INSERT ALL INTO test_1 VALUES(ID,t_desc) INTO test_2 VALUES(ID,t_desc)
SELECT 3 AS ID,'测试3' AS t_desc FROM dual;
--用其他表中值更新用merge into,匹配到了就修改,没有匹配到就插入
MERGE INTO test_1 USING(SELECT * FROM test_2) t2
ON (test_1.id = t2.id)
WHEN MATCHED THEN
UPDATE SET TEST_1.T_DESC = T2.T_DESC
WHEN NOT MATCHED THEN
INSERT (ID,T_DESC) VALUES(t2.id,t2.t_desc)
--translate函数与regexp_replace函数
SELECT TRANSLATE(zicplnnum,'-123444544','-'),zicplnnum ,listagg(zicplnnum,',') WITHIN GROUP (ORDER BY zicplnnum),wm_concat(zicplnnum)
FROM inventory_plans_details GROUP BY zicplnnum;
--累计合 对应的累计查用sum(case when) 变成负数
SELECT T.ZICPLNNUM, T.ZICEQUNR, T.ZICTIDNR,
SUM(T.ZICTIDNR) OVER(ORDER BY T.ZICSHTXT) 累计合,
(SELECT LISTAGG(B.ZICTIDNR, '+') WITHIN GROUP(ORDER BY B.ZICSHTXT) FROM SYS_TEST B
WHERE B.ZICSHTXT <= T.ZICSHTXT
AND B.ZICEQUNR = 1) 累计合公式
FROM SYS_TEST T
WHERE T.ZICEQUNR = 1 ORDER BY T.ZICSHTXT;
--取最大值最小值,根据开窗函数的排序用first_value取值
SELECT t.zicplnnum,t.zicequnr,t.zictidnr,
first_value(t.zictidnr) OVER(PARTITION BY t.zicequnr ORDER BY t.zictidnr desc) 最小值,
t.zicshtxt FROM sys_test t ORDER BY t.zicequnr,t.zictidnr ;
--比例函数ratio_to_report
SELECT T.ZICPLNNUM, T.ZICEQUNR, T.ZICTIDNR,T.ZICSHTXT,
ROUND(ratio_to_report(T.ZICTIDNR) OVER(PARTITION BY t.zicequnr) * 100,2) 占比例
FROM SYS_TEST T
ORDER BY T.ZICEQUNR;
--报表分组
-- ROLLUP和GROUPING函数的引用
--例外。可以使用GROUPING_ID来进行操作(值是GROUPING的十进制数)
SELECT NVL(ZICPLNNUM, '合计') ZICPLNNUM,
CASE
WHEN GROUPING(ZICPLNNUM) = 1 THEN
NULL
WHEN GROUPING(ZICEQUNR) = 1 THEN
'小计'
ELSE
ZICEQUNR
END AS 记录,
ZICEQUNR,
SUM(ZICTIDNR)
FROM INVENTORY_PLANS_DETAILS
GROUP BY ROLLUP(ZICPLNNUM, ZICEQUNR);
--cube 函数返回每一个组合的小计
select earnmonth, area, sum(personincome)
from earnings
group by cube(earnmonth,area)
order by earnmonth,area nulls last;
--行列转换操作
--PIVOT(列转行函数)将zictplnr列转换成对应的行
SELECT * FROM (SELECT zicplnnum,zictplnr FROM inventory_plans_details)
PIVOT( SUM(1) FOR zictplnr IN ('x' AS is_x,'xx' AS is_xx,'xxx' AS is_xxx));
--语法
SELECT ...
FROM ...
PIVOT [XML]
(pivot_clause
pivot_for_clause
pivot_in_clause )
WHERE ...
--UNPIVOT行转列函数
SELECT zicshtxt,ds FROM (SELECT zicshtxt , zicplnnum,zictplnr,NULL AS t_col FROM inventory_plans_details)
UNPIVOT INCLUDE NULLS (ds FOR col IN ( zicplnnum,zictplnr,t_col));
--语法
SELECT ...
FROM ...
UNPIVOT [INCLUDE|EXCLUDE NULLS]
(unpivot_clause
unpivot_for_clause
unpivot_in_clause )
WHERE ...
--执行计划查看
explain plan for SELECT * FROM (
SELECT ROWNUM AS sn ,t1.* FROM (
SELECT t.guid,t.filiale_id FROM dc_sys_company_info t ORDER BY t.filiale_id ) t1
WHERE ROWNUM <= 10) WHERE sn >5;
select * from table(dbms_xplan.display);
oracle for update和for update nowait的区别
http://www.cnblogs.com/quanweiru/archive/2012/11/09/2762223.html
oracle游标的定义使用
http://blog.163.com/ufsoftwhy@126/blog/static/40781436200812331257361/
游标是邪恶的!
http://www.cnblogs.com/moss_tan_jun/archive/2011/11/26/2263988.html
ORACLE 异常错误处理
http://www.cnblogs.com/soundcode/archive/2012/01/10/2318385.html
FORALL的使用
http://blog.csdn.net/indexman/article/details/9262915
表分区及维护
http://tianzt.blog.51cto.com/459544/171759/
Oracle的pipelined函数实现高性能大数据处理
http://mikixiyou.iteye.com/blog/1673672