sqlplus / as sysdba
sql> SELECT dbms_xdb.gethttpport FROM dual;
sql> EXEC dbms_xdb.sethttpport(0);
>COL comp_name FOR A30
>SELECT comp_name, version, status FROM dba_registry WHERE comp_id='APEX';
If there is already installed:
cd $ORACLE_HOME/apex
$ sqlplus / as sysdba
sql> @apxremov_con.sql
If the tablespace is not there already:
CREATE TABLESPACE APEX DATAFILE '/u02/oradata/snap11g/apex_01.dbf'
SIZE 200M REUSE AUTOEXTEND ON NEXT 10M MAXSIZE 1000M LOGGING
EXTENT MANAGEMENT LOCAL
SEGMENT SPACE MANAGEMENT AUTO;
sql> @apexins APEX APEX TEMP /i/
admin password :
sqlplus / as sysdba
sql> @apxchpwd
Under the old apex versions you can edit the script summoned by the apxchpwd.sql (apxxepwd.sql) such as the password can be as strong or weak as you wish. Under the newer versions, you can decide this only from the admin interface.
embedded PL/SQL Gateway configuration (EPG)
sql> @apex_epg_config.sql /u01/app/oracle/product/11.2.0.3/db_1
Update the APEX images for the new release
sql> @apxldimg.sql /u01/app/oracle/product/11.2.0.3/db_1
ALTER USER anonymous ACCOUNT UNLOCK;
ALTER USER xdb ACCOUNT UNLOCK;
ALTER USER apex_public_user ACCOUNT UNLOCK;
ALTER USER flows_files ACCOUNT UNLOCK;
enable the Oracle XML DB HTTP Server port (8080):
EXEC dbms_xdb.sethttpport(8080);
Enable remote HTTP connections (optional):
EXEC dbms_xdb.setListenerLocalAccess(l_access => FALSE);
marți, 19 ianuarie 2016
joi, 14 ianuarie 2016
ORA-39097: Data Pump job encountered unexpected error -12801 while expdp
ORA-39097: Data Pump job encountered unexpected error -12801
ORA-39065: unexpected master process exception in MAIN
ORA-12801: error signaled in parallel query server P..., instance <instance_name>
ORA-01460: unimplemented or unreasonable conversion requested Job <job_name> stopped due to fatal error at <failure_time>.
The problem seems to be a bug and the solution can be an update to minimum 11.2.0.4 version.
For me, the workaround was:
> alter system set PARALLEL_FORCE_LOCAL=TRUE;
ORA-39065: unexpected master process exception in MAIN
ORA-12801: error signaled in parallel query server P..., instance <instance_name>
ORA-01460: unimplemented or unreasonable conversion requested Job <job_name> stopped due to fatal error at <failure_time>.
The problem seems to be a bug and the solution can be an update to minimum 11.2.0.4 version.
For me, the workaround was:
> alter system set PARALLEL_FORCE_LOCAL=TRUE;
miercuri, 6 ianuarie 2016
Create audit triggers for all the tables of a schema and audit tables in another schema
First, create the owner of the audit tables (in our scenario, will be "john_audit" and the audited schema will be "john"). Be aware that the audit user should mandatory name like audited name + "_audit".
CREATE OR REPLACE PROCEDURE create_audit_tables (table_owner VARCHAR2)
IS
CURSOR c_tables (
table_owner VARCHAR2)
IS
SELECT ot.owner AS owner, ot.table_name AS table_name
FROM all_tables ot
WHERE lower( ot.owner) = lower(table_owner)
;
aud_user varchar2(100);
v_sql VARCHAR2 (8000);
v_count1 number;
v_count2 number;
v_count NUMBER := 0;
v_aud VARCHAR2 (30);
n_count number;
BEGIN
aud_user:=table_owner||'_AUDIT';
select count(*) into v_count1 from dba_tables where lower(owner)=lower(table_owner);
select count(*) into v_count2 from dba_tables where lower(owner)=lower(aud_user);
v_count:=v_count1-v_count2;
if v_count>0 then
FOR r_table IN c_tables (table_owner)
LOOP
BEGIN
v_aud := r_table.table_name;
select count(*) into n_count from dba_tables where lower(table_name)=lower(v_aud) and lower(owner)=lower(aud_user);
if n_count=0 then
v_sql :=
'create table '||aud_user
|| '.'
|| v_aud
|| ' as select * from '
|| r_table.owner
|| '.'
|| r_table.table_name
|| ' where 0 = 1';
DBMS_OUTPUT.put_line ('Info: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
v_sql :=
'alter table '||aud_user||'.'
|| v_aud
|| ' add ( AUDIT_ACTION char(1), AUDIT_BY varchar2(50), AUDIT_AT TIMESTAMP)';
EXECUTE IMMEDIATE v_sql;
end if;
-- v_count := c_tables%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create table '
|| v_aud
|| ' due to '
|| SQLERRM);
END;
END LOOP;
end if;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit tables created');
ELSE
DBMS_OUTPUT.put_line (v_count || ' audit tables created.');
END IF;
END;
/
Run the procedure (will create audit tables in audit schema only for the tables created after the last run):
begin
create_audit_tables('john'); --it's not caps sensitive
end;
/
Now, a function which will gatter the columns together:
create or replace FUNCTION get_columns_for_table (
table_owner VARCHAR2,
t_name VARCHAR2,
prefix VARCHAR2
) RETURN CLOB
IS
v_text CLOB;
BEGIN
FOR getrec IN (SELECT column_name
FROM all_tab_columns
WHERE table_name = t_name
AND owner = table_owner
AND data_type<>'BLOB')
LOOP
v_text := v_text
|| ','
|| prefix
|| getrec.column_name
|| CHR (10)
|| ' ';
END LOOP;
RETURN ltrim(v_text,',');
END;
And a function that will compare the old and new columns values, in order to find if an update applied.
create or replace function get_column_comparison (
table_owner VARCHAR2,
t_name VARCHAR2
) RETURN CLOB
IS
v_text CLOB;
BEGIN
FOR getrec IN (SELECT column_name
FROM all_tab_columns
WHERE table_name = t_name
AND owner = table_owner
AND data_type<>'BLOB')
LOOP
v_text := v_text
|| ' or( (:old.'
|| getrec.column_name
|| ' <> :new.'
|| getrec.column_name
|| ') or (:old.'
|| getrec.column_name
|| ' IS NULL and :new.'
|| getrec.column_name
|| ' IS NOT NULL) or (:old.'
|| getrec.column_name
|| ' IS NOT NULL and :new.'
|| getrec.column_name
|| ' IS NULL))'
|| CHR (10)
|| ' ';
END LOOP;
v_text := LTRIM (v_text, ' or');
RETURN v_text;
END;
And now the procedure that will produce the triggers:
CREATE OR REPLACE PROCEDURE create_audit_triggers (table_owner VARCHAR2)
IS
CURSOR c_tab_inc (
table_owner VARCHAR2)
IS
SELECT ot.owner AS owner, ot.table_name AS table_name
FROM all_tables ot
WHERE lower (ot.owner) =lower ( table_owner)
;
aud_user varchar2 (100);
v_query VARCHAR2 (32767);
v_count NUMBER := 0;
BEGIN
aud_user:=table_owner||'_AUDIT';
-- the triggers should have privileges in the audit schema
FOR c IN (SELECT owner, table_name FROM all_tables WHERE lower(owner)=lower(aud_user))
LOOP
EXECUTE IMMEDIATE 'grant select,insert,update on '||c.owner||'.'||c.table_name||' to '||table_owner;
END LOOP;
FOR r_tab_inc IN c_tab_inc (table_owner)
LOOP
BEGIN
v_query :=
'CREATE OR REPLACE TRIGGER '
||table_owner
|| '.A'
|| substr(r_tab_inc.table_name,1,29)
|| ' AFTER INSERT OR UPDATE OR DELETE ON '
|| r_tab_inc.owner
|| '.'
|| r_tab_inc.table_name
|| ' FOR EACH ROW'
|| CHR (10)
|| 'DECLARE '
|| CHR (10)
|| ' v_user varchar2(30):=null;'
|| CHR (10)
|| ' v_action varchar2(15);'
|| CHR (10)
|| 'BEGIN'
|| CHR (10)
|| ' SELECT SYS_CONTEXT (''USERENV'', ''session_user'') session_user'
|| CHR (10)
|| ' INTO v_user'
|| CHR (10)
|| ' FROM DUAL;'
|| CHR (10)
|| ' if inserting then '
|| CHR (10)
|| ' v_action:=''INSERT'';'
|| CHR (10)
|| ' insert into '
|| aud_user
|| '.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':new.')
|| ' ,''I'',v_user,SYSDATE);'
|| CHR (10)
|| ' elsif updating then '
|| CHR (10)
|| ' v_action:=''UPDATE'';'
|| CHR (10)
|| ' if '
|| get_column_comparison (r_tab_inc.owner, r_tab_inc.table_name)
|| ' then '
|| CHR (10)
|| ' insert into '
||aud_user
||'.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':new.')
|| ' ,''U'',v_user,SYSDATE);'
|| CHR (10)
|| ' end if;'
|| ' elsif deleting then'
|| CHR (10)
|| ' v_action:=''DELETING'';'
|| CHR (10)
|| ' insert into '
||aud_user
||'.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':old.')
|| ' ,''D'',v_user,SYSDATE);'
|| CHR (10)
|| ' end if;'
|| CHR (10)
|| 'END;';
DBMS_OUTPUT.put_line (
'CREATE TRIGGER '
|| REPLACE (r_tab_inc.table_name, 'TABLE_', 'TRIGGER_'));
EXECUTE IMMEDIATE v_query;
DBMS_OUTPUT.put_line (
'Audit trigger '
|| REPLACE (r_tab_inc.table_name, 'TABLE_', 'TRIGGER_')
|| ' created.');
v_count := c_tab_inc%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create audit trigger for '
|| r_tab_inc.owner
|| '.'
|| r_tab_inc.table_name
|| ' due to '
|| SQLERRM);
END;
END LOOP;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit triggers created');
END IF;
END;
/
Notice the sequence which grant the audited user to modify any table from the audit schema, created before with the create_audit_tables procedure.
Now, all you have to do is to run the procedure and you will create as many triggers as tables they are. The triggers will be either created or replaced, so the procedure will run for every single table in the schema, no mother if it was created after the last run of the
create_audit_tables procedure or not.
begin
CREATE_AUDIT_TRIGGERS('john');
end;
/
CREATE OR REPLACE PROCEDURE create_audit_tables (table_owner VARCHAR2)
IS
CURSOR c_tables (
table_owner VARCHAR2)
IS
SELECT ot.owner AS owner, ot.table_name AS table_name
FROM all_tables ot
WHERE lower( ot.owner) = lower(table_owner)
;
aud_user varchar2(100);
v_sql VARCHAR2 (8000);
v_count1 number;
v_count2 number;
v_count NUMBER := 0;
v_aud VARCHAR2 (30);
n_count number;
BEGIN
aud_user:=table_owner||'_AUDIT';
select count(*) into v_count1 from dba_tables where lower(owner)=lower(table_owner);
select count(*) into v_count2 from dba_tables where lower(owner)=lower(aud_user);
v_count:=v_count1-v_count2;
if v_count>0 then
FOR r_table IN c_tables (table_owner)
LOOP
BEGIN
v_aud := r_table.table_name;
select count(*) into n_count from dba_tables where lower(table_name)=lower(v_aud) and lower(owner)=lower(aud_user);
if n_count=0 then
v_sql :=
'create table '||aud_user
|| '.'
|| v_aud
|| ' as select * from '
|| r_table.owner
|| '.'
|| r_table.table_name
|| ' where 0 = 1';
DBMS_OUTPUT.put_line ('Info: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
v_sql :=
'alter table '||aud_user||'.'
|| v_aud
|| ' add ( AUDIT_ACTION char(1), AUDIT_BY varchar2(50), AUDIT_AT TIMESTAMP)';
EXECUTE IMMEDIATE v_sql;
end if;
-- v_count := c_tables%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create table '
|| v_aud
|| ' due to '
|| SQLERRM);
END;
END LOOP;
end if;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit tables created');
ELSE
DBMS_OUTPUT.put_line (v_count || ' audit tables created.');
END IF;
END;
/
Run the procedure (will create audit tables in audit schema only for the tables created after the last run):
begin
create_audit_tables('john'); --it's not caps sensitive
end;
/
Now, a function which will gatter the columns together:
create or replace FUNCTION get_columns_for_table (
table_owner VARCHAR2,
t_name VARCHAR2,
prefix VARCHAR2
) RETURN CLOB
IS
v_text CLOB;
BEGIN
FOR getrec IN (SELECT column_name
FROM all_tab_columns
WHERE table_name = t_name
AND owner = table_owner
AND data_type<>'BLOB')
LOOP
v_text := v_text
|| ','
|| prefix
|| getrec.column_name
|| CHR (10)
|| ' ';
END LOOP;
RETURN ltrim(v_text,',');
END;
And a function that will compare the old and new columns values, in order to find if an update applied.
create or replace function get_column_comparison (
table_owner VARCHAR2,
t_name VARCHAR2
) RETURN CLOB
IS
v_text CLOB;
BEGIN
FOR getrec IN (SELECT column_name
FROM all_tab_columns
WHERE table_name = t_name
AND owner = table_owner
AND data_type<>'BLOB')
LOOP
v_text := v_text
|| ' or( (:old.'
|| getrec.column_name
|| ' <> :new.'
|| getrec.column_name
|| ') or (:old.'
|| getrec.column_name
|| ' IS NULL and :new.'
|| getrec.column_name
|| ' IS NOT NULL) or (:old.'
|| getrec.column_name
|| ' IS NOT NULL and :new.'
|| getrec.column_name
|| ' IS NULL))'
|| CHR (10)
|| ' ';
END LOOP;
v_text := LTRIM (v_text, ' or');
RETURN v_text;
END;
And now the procedure that will produce the triggers:
CREATE OR REPLACE PROCEDURE create_audit_triggers (table_owner VARCHAR2)
IS
CURSOR c_tab_inc (
table_owner VARCHAR2)
IS
SELECT ot.owner AS owner, ot.table_name AS table_name
FROM all_tables ot
WHERE lower (ot.owner) =lower ( table_owner)
;
aud_user varchar2 (100);
v_query VARCHAR2 (32767);
v_count NUMBER := 0;
BEGIN
aud_user:=table_owner||'_AUDIT';
-- the triggers should have privileges in the audit schema
FOR c IN (SELECT owner, table_name FROM all_tables WHERE lower(owner)=lower(aud_user))
LOOP
EXECUTE IMMEDIATE 'grant select,insert,update on '||c.owner||'.'||c.table_name||' to '||table_owner;
END LOOP;
FOR r_tab_inc IN c_tab_inc (table_owner)
LOOP
BEGIN
v_query :=
'CREATE OR REPLACE TRIGGER '
||table_owner
|| '.A'
|| substr(r_tab_inc.table_name,1,29)
|| ' AFTER INSERT OR UPDATE OR DELETE ON '
|| r_tab_inc.owner
|| '.'
|| r_tab_inc.table_name
|| ' FOR EACH ROW'
|| CHR (10)
|| 'DECLARE '
|| CHR (10)
|| ' v_user varchar2(30):=null;'
|| CHR (10)
|| ' v_action varchar2(15);'
|| CHR (10)
|| 'BEGIN'
|| CHR (10)
|| ' SELECT SYS_CONTEXT (''USERENV'', ''session_user'') session_user'
|| CHR (10)
|| ' INTO v_user'
|| CHR (10)
|| ' FROM DUAL;'
|| CHR (10)
|| ' if inserting then '
|| CHR (10)
|| ' v_action:=''INSERT'';'
|| CHR (10)
|| ' insert into '
|| aud_user
|| '.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':new.')
|| ' ,''I'',v_user,SYSDATE);'
|| CHR (10)
|| ' elsif updating then '
|| CHR (10)
|| ' v_action:=''UPDATE'';'
|| CHR (10)
|| ' if '
|| get_column_comparison (r_tab_inc.owner, r_tab_inc.table_name)
|| ' then '
|| CHR (10)
|| ' insert into '
||aud_user
||'.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':new.')
|| ' ,''U'',v_user,SYSDATE);'
|| CHR (10)
|| ' end if;'
|| ' elsif deleting then'
|| CHR (10)
|| ' v_action:=''DELETING'';'
|| CHR (10)
|| ' insert into '
||aud_user
||'.'
|| r_tab_inc.table_name
|| '('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
NULL)
|| ' ,AUDIT_ACTION,AUDIT_BY,AUDIT_AT)'
|| CHR (10)
|| ' values ('
|| get_columns_for_table (r_tab_inc.owner,
r_tab_inc.table_name,
':old.')
|| ' ,''D'',v_user,SYSDATE);'
|| CHR (10)
|| ' end if;'
|| CHR (10)
|| 'END;';
DBMS_OUTPUT.put_line (
'CREATE TRIGGER '
|| REPLACE (r_tab_inc.table_name, 'TABLE_', 'TRIGGER_'));
EXECUTE IMMEDIATE v_query;
DBMS_OUTPUT.put_line (
'Audit trigger '
|| REPLACE (r_tab_inc.table_name, 'TABLE_', 'TRIGGER_')
|| ' created.');
v_count := c_tab_inc%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create audit trigger for '
|| r_tab_inc.owner
|| '.'
|| r_tab_inc.table_name
|| ' due to '
|| SQLERRM);
END;
END LOOP;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit triggers created');
END IF;
END;
/
Notice the sequence which grant the audited user to modify any table from the audit schema, created before with the create_audit_tables procedure.
Now, all you have to do is to run the procedure and you will create as many triggers as tables they are. The triggers will be either created or replaced, so the procedure will run for every single table in the schema, no mother if it was created after the last run of the
create_audit_tables procedure or not.
begin
CREATE_AUDIT_TRIGGERS('john');
end;
/
Create incrementing triggers for all the PKs from all the tables of a schema
This is the procedure:
CREATE OR REPLACE PROCEDURE create_pk_triggers (table_owner VARCHAR2)
IS
CURSOR c_tables (
table_owner VARCHAR2)
IS
select * FROM ALL_CONS_COLUMNS
WHERE
CONSTRAINT_NAME IN ( SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS where CONSTRAINT_TYPE = 'P') and
lower(owner)=lower(table_owner);
v_sql VARCHAR2 (8000);
v_count NUMBER := 0;
v_aud VARCHAR2 (30);
v_col varchar2(50);
BEGIN
FOR r_table IN c_tables (table_owner)
LOOP
BEGIN
v_aud := r_table.table_name;
v_col := r_table.column_name;
v_sql :=
'CREATE OR REPLACE TRIGGER inspk_'
||substr(v_aud,1,24)
|| CHR (10)
||' before insert on '
||table_owner
||'.'
|| v_aud
|| CHR (10)
|| ' for each row begin '
|| CHR (10)
|| ' if inserting and :new.'
|| v_col
|| ' is null then '
|| CHR (10)
|| ':new.'
|| v_col
|| ' :='
|| ' call4prop_seq.nextval;'
|| CHR (10)
|| ' end if;'
|| CHR (10)
|| ' end;'
;
DBMS_OUTPUT.put_line ('Info: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
v_count := c_tables%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create table '
|| v_aud
|| ' due to '
|| SQLERRM);
END;
END LOOP;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit tables created');
ELSE
DBMS_OUTPUT.put_line (v_count || ' audit tables created.');
END IF;
END;
/
And here is how to run the procedure, using as a parameter the name of the schema owner (the capitals rule will not apply):
begin
create_pk_triggers('username');
end;
/
CREATE OR REPLACE PROCEDURE create_pk_triggers (table_owner VARCHAR2)
IS
CURSOR c_tables (
table_owner VARCHAR2)
IS
select * FROM ALL_CONS_COLUMNS
WHERE
CONSTRAINT_NAME IN ( SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS where CONSTRAINT_TYPE = 'P') and
lower(owner)=lower(table_owner);
v_sql VARCHAR2 (8000);
v_count NUMBER := 0;
v_aud VARCHAR2 (30);
v_col varchar2(50);
BEGIN
FOR r_table IN c_tables (table_owner)
LOOP
BEGIN
v_aud := r_table.table_name;
v_col := r_table.column_name;
v_sql :=
'CREATE OR REPLACE TRIGGER inspk_'
||substr(v_aud,1,24)
|| CHR (10)
||' before insert on '
||table_owner
||'.'
|| v_aud
|| CHR (10)
|| ' for each row begin '
|| CHR (10)
|| ' if inserting and :new.'
|| v_col
|| ' is null then '
|| CHR (10)
|| ':new.'
|| v_col
|| ' :='
|| ' call4prop_seq.nextval;'
|| CHR (10)
|| ' end if;'
|| CHR (10)
|| ' end;'
;
DBMS_OUTPUT.put_line ('Info: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
v_count := c_tables%ROWCOUNT;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Failed to create table '
|| v_aud
|| ' due to '
|| SQLERRM);
END;
END LOOP;
IF v_count = 0
THEN
DBMS_OUTPUT.put_line ('No audit tables created');
ELSE
DBMS_OUTPUT.put_line (v_count || ' audit tables created.');
END IF;
END;
/
And here is how to run the procedure, using as a parameter the name of the schema owner (the capitals rule will not apply):
begin
create_pk_triggers('username');
end;
/
Abonați-vă la:
Postări (Atom)