or.....
option #4, just run "70" union all queries (unioning current with history) and get the precise columns you need from each for the report.... (i would not concatenate unless that is how the report was to be printed, I would definitely not use a temporary table)
option #5, use workspace manager and let it do the versioning for you and you just "dbms_wm.goto_date()" to query the data as of a point in time!
</code>
http://docs.oracle.com/cd/B14117_01/appdev.101/b10824/toc.htm <code>
we'll start off by creating a WSMGMT user with the appropriate privs
ops$tkyte@ORA10G> CREATE USER wsmgmt IDENTIFIED BY wsmgmt;
User created.
ops$tkyte@ORA10G> GRANT connect, resource, create table to wsmgmt;
Grant succeeded.
ops$tkyte@ORA10G> begin
2 DBMS_WM.GrantSystemPriv
3 ('ACCESS_ANY_WORKSPACE, MERGE_ANY_WORKSPACE, ' ||
4 'CREATE_ANY_WORKSPACE, REMOVE_ANY_WORKSPACE, ' ||
5 'ROLLBACK_ANY_WORKSPACE', 'WSMGMT', 'YES');
6 end;
7 /
PL/SQL procedure successfully completed.
ops$tkyte@ORA10G> set echo off
scott@ORA10G>
scott@ORA10G>
scott@ORA10G> set echo off
Now we'll log in as wsmgmt and set up our schema...
wsmgmt@ORA10G> create table emp as select * from scott.emp;
wsmgmt@ORA10G> create table dept as select * from scott.dept;
wsmgmt@ORA10G> alter table emp add constraint emp_pk primary key(empno);
wsmgmt@ORA10G> alter table dept add constraint dept_pk primary key(deptno);
wsmgmt@ORA10G> alter table emp add constraint emp_fk_dept foreign key(deptno)
2 references dept(deptno);
wsmgmt@ORA10G> alter table emp add constraint emp_fk_emp foreign key(mgr)
2 references emp(empno);
wsmgmt@ORA10G> set feedback on
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Version-enable the table. Specify hist option of VIEW_WO_OVERWRITE so that
the xxx_HIST view contains complete history information.
wsmgmt@ORA10G> begin
2 DBMS_WM.EnableVersioning ('emp', 'VIEW_WO_OVERWRITE');
3 DBMS_WM.EnableVersioning ('dept', 'VIEW_WO_OVERWRITE');
4 end;
5 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> column t new_val t
wsmgmt@ORA10G> select to_char(sysdate,'yyyymmddhh24miss') t from dual;
T
--------------
20050214103154
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Next, create workspaces, these workspaces will have their own views
of the data...
wsmgmt@ORA10G> begin
2 DBMS_WM.CreateWorkspace ('ws1');
3 DBMS_WM.CreateWorkspace ('ws2');
4 end;
5 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
By default, we are in the LIVE workspace, now lets get into workspace ws1
wsmgmt@ORA10G> begin
2 DBMS_WM.GotoWorkspace ('ws1');
3 end;
4 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
In this workspace, we'll update the emp table, LIVE/ws2 cannot see this
wsmgmt@ORA10G> update emp set sal = sal * 1.10;
14 rows updated.
wsmgmt@ORA10G> commit;
Commit complete.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Here is the history and current view now for one of the rows of interest
wsmgmt@ORA10G> select ename, sal, comm, wm_workspace, wm_optype,
2 to_char(wm_createtime,'dd-mon hh24:mi:ss') created,
3 to_char(wm_retiretime,'dd-mon hh24:mi:ss') retired
4 from emp_hist where ename = 'KING';
ENAME SAL COMM WM_WOR W CREATED RETIRED
---------- ---------- ---------- ------ - --------------- ---------------
KING 5000 LIVE I 14-feb 10:31:49
KING 5500 ws1 U 14-feb 10:31:54
2 rows selected.
wsmgmt@ORA10G> select ename, sal, comm
2 from emp where ename = 'KING';
ENAME SAL COMM
---------- ---------- ----------
KING 5500
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Lets do another mass update and see the effects of that
wsmgmt@ORA10G> update emp set comm = 0.1 * (greatest(0,sal-1000));
14 rows updated.
wsmgmt@ORA10G> commit;
Commit complete.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Notice the history has retired records now
wsmgmt@ORA10G> select ename, sal, comm, wm_workspace, wm_optype,
2 to_char(wm_createtime,'dd-mon hh24:mi:ss') created,
3 to_char(wm_retiretime,'dd-mon hh24:mi:ss') retired
4 from emp_hist where ename = 'KING';
ENAME SAL COMM WM_WOR W CREATED RETIRED
---------- ---------- ---------- ------ - --------------- ---------------
KING 5000 LIVE I 14-feb 10:31:49
KING 5500 ws1 U 14-feb 10:31:54 14-feb 10:31:55
KING 5500 450 ws1 U 14-feb 10:31:55
3 rows selected.
wsmgmt@ORA10G> select ename, sal, comm from emp where ename = 'KING';
ENAME SAL COMM
---------- ---------- ----------
KING 5500 450
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
See how LIVE cannot see these changes as yet
wsmgmt@ORA10G> begin
2 DBMS_WM.GotoWorkspace ('LIVE');
3 end;
4 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> select ename, sal, comm
2 from emp
3 where ename = 'KING'
4 /
ENAME SAL COMM
---------- ---------- ----------
KING 5000
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
nor can ws2
wsmgmt@ORA10G> begin
2 DBMS_WM.GotoWorkspace ('ws2');
3 end;
4 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> select ename, sal, comm
2 from emp
3 where ename = 'KING'
4 /
ENAME SAL COMM
---------- ---------- ----------
KING 5000
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
here we will update a row we know has been modified in another workspace
we could use long term locking to avoid this (but we didn't)
wsmgmt@ORA10G> update emp set sal = sal * 1.5 where ename = 'KING';
1 row updated.
wsmgmt@ORA10G> update emp set comm = 0.1 * (greatest(0,sal-1000)) where ename = 'KING';
1 row updated.
wsmgmt@ORA10G> commit;
Commit complete.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Notice the history for the KING row across workspaces..
wsmgmt@ORA10G> select ename, sal, comm, wm_workspace, wm_optype,
2 to_char(wm_createtime,'dd-mon hh24:mi:ss') created,
3 to_char(wm_retiretime,'dd-mon hh24:mi:ss') retired
4 from emp_hist where ename = 'KING';
ENAME SAL COMM WM_WOR W CREATED RETIRED
---------- ---------- ---------- ------ - --------------- ---------------
KING 5000 LIVE I 14-feb 10:31:49
KING 5500 ws1 U 14-feb 10:31:54 14-feb 10:31:55
KING 5500 450 ws1 U 14-feb 10:31:55
KING 7500 ws2 U 14-feb 10:31:55 14-feb 10:31:55
KING 7500 650 ws2 U 14-feb 10:31:55
5 rows selected.
wsmgmt@ORA10G> select ename, sal, comm from emp where ename = 'KING';
ENAME SAL COMM
---------- ---------- ----------
KING 7500 650
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
Lets check out this savepoint feature, we want to be able to
come back to this point in time in this workspace for whatever reason
wsmgmt@ORA10G> begin
2 DBMS_WM.CreateSavepoint ('ws2', 'ws2_SP1');
3 end;
4 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
We want to what-if a coup. Blake is taking over...
wsmgmt@ORA10G>
wsmgmt@ORA10G> update emp
2 set mgr = ( select empno from emp where ename = 'BLAKE' )
3 where mgr = ( select empno from emp where ename = 'KING' );
3 rows updated.
wsmgmt@ORA10G> delete from emp where ename = 'KING';
1 row deleted.
wsmgmt@ORA10G> delete from dept where deptno = 40;
1 row deleted.
wsmgmt@ORA10G> commit;
Commit complete.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
the changes are all made now... and committed
wsmgmt@ORA10G> select ename, mgr, sal, comm from emp;
ENAME MGR SAL COMM
---------- ---------- ---------- ----------
SMITH 7902 800
ALLEN 7698 1600 300
WARD 7698 1250 500
MARTIN 7698 1250 1400
TURNER 7698 1500 0
ADAMS 7788 1100
JAMES 7698 950
FORD 7566 3000
MILLER 7782 1300
SCOTT 7566 3000
JONES 7698 2975
BLAKE 7698 2850
CLARK 7698 2450
13 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
3 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
but king mounts a counter attack and comes back...
wsmgmt@ORA10G> begin
2 DBMS_WM.GotoWorkspace ('LIVE');
3 DBMS_WM.RollbackToSP ('ws2', 'ws2_SP1');
4 DBMS_WM.GotoWorkspace ('ws2');
5 end;
6 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G> select ename, sal, comm, wm_workspace, wm_optype,
2 to_char(wm_createtime,'dd-mon hh24:mi:ss') created,
3 to_char(wm_retiretime,'dd-mon hh24:mi:ss') retired
4 from emp_hist where ename = 'KING';
ENAME SAL COMM WM_WOR W CREATED RETIRED
---------- ---------- ---------- ------ - --------------- ---------------
KING 5000 LIVE I 14-feb 10:31:49
KING 5500 ws1 U 14-feb 10:31:54 14-feb 10:31:55
KING 5500 450 ws1 U 14-feb 10:31:55
KING 7500 ws2 U 14-feb 10:31:55 14-feb 10:31:55
KING 7500 650 ws2 U 14-feb 10:31:55
5 rows selected.
wsmgmt@ORA10G> select ename, sal, comm from emp where ename = 'KING';
ENAME SAL COMM
---------- ---------- ----------
KING 7500 650
1 row selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
now we would like to merge the changes into the LIVE workspace from ws1
wsmgmt@ORA10G> EXECUTE DBMS_WM.GotoWorkspace ('LIVE');
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G> select ename, sal, comm from emp;
ENAME SAL COMM
---------- ---------- ----------
SMITH 800
ALLEN 1600 300
WARD 1250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
KING 5000
TURNER 1500 0
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300
SCOTT 3000
14 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
That was easy enough... However
wsmgmt@ORA10G> EXECUTE DBMS_WM.MergeWorkspace ('ws1');
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G> select ename, sal, comm from emp;
ENAME SAL COMM
---------- ---------- ----------
MILLER 1430 43
FORD 3300 230
JAMES 1045 4.5
ADAMS 1210 21
TURNER 1650 65
KING 5500 450
SCOTT 3300 230
CLARK 2695 169.5
BLAKE 3135 213.5
MARTIN 1375 37.5
JONES 3272.5 227.25
WARD 1375 37.5
ALLEN 1760 76
SMITH 880 0
14 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
ws2 gives us some hard times -- there is a conflict we have to resolve
wsmgmt@ORA10G> EXECUTE DBMS_WM.MergeWorkspace ('ws2');
BEGIN DBMS_WM.MergeWorkspace ('ws2'); END;
*
ERROR at line 1:
ORA-20055: conflicts detected for workspace: 'ws2' in table: 'WSMGMT.EMP'
ORA-06512: at "SYS.LT", line 5852
ORA-06512: at line 1
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
going into that workspace, we can see the conflicts and decide how to resolve
them
wsmgmt@ORA10G> EXECUTE DBMS_WM.GotoWorkspace ('ws2');
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> select * from emp_conf;
WM_W EMPNO ENAME JOB HIREDATE SAL COMM DEPTNO WM_
---- ---------- ---------- --------- --------- ----- ---- ------ ---
ws2 7839 KING PRESIDENT 17-NOV-81 7500 650 10 NO
BASE 7839 KING PRESIDENT 17-NOV-81 5000 10 NO
LIVE 7839 KING PRESIDENT 17-NOV-81 5500 450 10 NO
3 rows selected.
wsmgmt@ORA10G> set echo off
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
we decide the child should win....
wsmgmt@ORA10G> begin
2 DBMS_WM.BeginResolve( 'ws2' );
3 DBMS_WM.ResolveConflicts('ws2',
4 'emp',
5 'empno = 7839',
6 'CHILD' );
7 commit;
8 DBMS_WM.CommitResolve( 'ws2' );
9 end;
10 /
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
and now we can merge easily...
wsmgmt@ORA10G> execute dbms_wm.gotoWorkspace( 'LIVE' );
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> EXECUTE DBMS_WM.MergeWorkspace ('ws2');
PL/SQL procedure successfully completed.
wsmgmt@ORA10G> select ename, sal, comm from emp;
ENAME SAL COMM
---------- ---------- ----------
KING 7500 650
MILLER 1430 43
FORD 3300 230
JAMES 1045 4.5
ADAMS 1210 21
TURNER 1650 65
SCOTT 3300 230
CLARK 2695 169.5
BLAKE 3135 213.5
MARTIN 1375 37.5
JONES 3272.5 227.25
WARD 1375 37.5
ALLEN 1760 76
SMITH 880 0
14 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G> exec dbms_wm.gotodate( to_date('&T','yyyymmddhh24miss') )
PL/SQL procedure successfully completed.
wsmgmt@ORA10G>
wsmgmt@ORA10G> select ename, sal, comm from emp;
ENAME SAL COMM
---------- ---------- ----------
SMITH 800
ALLEN 1600 300
WARD 1250 500
JONES 2975
MARTIN 1250 1400
BLAKE 2850
CLARK 2450
KING 5000
TURNER 1500 0
ADAMS 1100
JAMES 950
FORD 3000
MILLER 1300
SCOTT 3000
14 rows selected.
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G>
wsmgmt@ORA10G> set echo off
a little cleanup and we are done...