首先建表emp_2017,结构要和emp完全一致。如果不一致,就要将下边代码块中的星号改成需要的内容。
MOD(N,10) = 0,这里的N,是要emp里一个分别比较均匀的数字类型字段,不能有空值。10是需要分成的进程数,0是第一个进程,还可以改成1,就是第二个进程……,一直到9,就是第十个进程。
DECLARE
i NUMBER;
cr emp%rowtype;
CURSOR userrows IS
SELECT
*
FROM
emp
WHERE
year = '2017'
AND
mod(n,10) = 0;
BEGIN
i := 0;
FOR c IN cr LOOP
INSERT INTO emp_2017 ( column_name1,column_name2,column_name3…… ) VALUES (
c.column_name1,
c.column_name2,
c.column_name3……
);
IF
i >= 1000
THEN
i := 0;
COMMIT;
END IF;
i := i + 1;
END LOOP;
COMMIT;
END;
完全没必要用存储过程。
1、可以直接shell 后台跑 eg
export ORACLE_SID=ORCL
vi m_t.sh
sqlplus -s / as sysdba <<EOF >> ./logfile
set serveroutput on;
set timing on;
alter session set nls_date_format='yyyymmdd HH24:MI:SS';
select sysdate from dual;
create table emp_20190731 nologging as select * /*+ parallel 4*/ from emp where id=2017;
select sysdate from dual;
create table emp_20190831 nologging as select * /*+ parallel 4*/ from emp where id=2018;
select sysdate from dual;
prompt get count from emp_20190731 emp_20190831;
select count(1) cnt, 'emp_20190731' as tname from emp_20190731;
select count(1) cnt, 'emp_20190831' as tname from emp_20190831;
select sysdate from dual;
exit;
EOF
sh m_t.sh >> /dev/null 2>&1 &
2、
也可以写存储过程
create or replace procedure bak_t (bak_name in varchar2, t_name in varchar2 , t_where in varchar2 )
as
v_sql varvhar2(2000);
begin
v_sql := 'create table '||bak_name||' nologging as select /*+ parallel 4*/ * from '||t_name||' where id= '||t_where;
dbms_output.put_line (v_sql);
execute immediate v_sql ;
end;
调用 plsql
call bak_t ('bak_emp_2017','emp',2017);
或者
begin
bak_t ('bak_emp_2017','emp',2017);
end;
sqlplus 中可以直接用
exec bak_t ('bak_emp_2017','emp',2017);
也可以用begin end 调用。
3、建议用 shell 加proc