仅仅是把一个表得数据复制到另一个表,emp表有几十亿得数据,现在想将2017年得数据用一张表存储,2018年用一张表,仅仅用sql跑得话很浪费时间,想用存储过程在后台自己跑。
create table emp_20190731 as select * from emp 
想把上面得语句用存储过程在后台实现,可自己没学过,百度是没实现自己想要得
求助一下。

解决方案 »

  1.   

    那你得好好看一下存储过程的创建及使用。往年的数据如果不更新的话,直接用sql加上时间限定条件,执行很快的。今年的数据可以放到存储过程中,再用job通过日志的方式控制增量,这样可以实现自动添加和更新,记得加索引,不然要崩溃
      

  2.   

    完全没必要用存储过程。
    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;
    EOFsh 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
      

  3.   

    首先建表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;