ALTER TABLE OU_REF.QUOT_BASIS_MAP ADD CONSTRAINT CHECK_ANALYZED CHECK (UPPER(ANNUALIZED) IN ( 'U', 'N', 'Y'));

GRANT SELECT ANY TABLE ON SCHEMA DW_REF_MAIN TO OU_REF;
GRANT INSERT ANY TABLE ON SCHEMA DW_REF_MAIN TO OU_REF;
GRANT UPDATE ANY TABLE ON SCHEMA DW_REF_MAIN TO OU_REF;
GRANT DELETE ANY TABLE ON SCHEMA DW_REF_MAIN TO OU_REF;

GRANT SELECT ANY TABLE ON SCHEMA REFERENCE TO OU_REF;
GRANT INSERT ANY TABLE ON SCHEMA REFERENCE TO OU_REF;
GRANT UPDATE ANY TABLE ON SCHEMA REFERENCE TO OU_REF;
GRANT DELETE ANY TABLE ON SCHEMA REFERENCE TO OU_REF;

SET SERVEROUTPUT ON;
DECLARE
  v_ins_str VARCHAR2(4096);
  v_upd_str VARCHAR2(4096);
  v_trigger_sql VARCHAR2(32767);
  v_trigger_name VARCHAR2(128);
  v_ref_table_name VARCHAR2(128);
  v_table_name VARCHAR2(128); -- GIVE VALUE FOR ONE TABLE TRIGGER GENERATION
BEGIN
  FOR i IN (
    SELECT 
      OWNER, TABLE_NAME 
    FROM DBA_TABLES t 
    WHERE 
        OWNER = 'OU_REF' 
    AND (v_table_name IS NULL OR TABLE_NAME = v_table_name) 
    AND TABLE_NAME IN (
    'ASSET_CODE_TYPE', 'ABS_TYPE', 'ALLOTMENT_METHOD', 'AREA_CODE_RIAD', 'ASSET_GROUP_DETAIL', 'ASSET_GROUP_MAPPING', 'ASSET_GROUP_TMS', 'ASSET_GROUP_TMS_OLD_NEW_MAP', 'ASSET_TYPE', 'ASSET_TYPE_TMS',  
    'CSPP_BENCHMARK', 'CSPP_GROUP_MEMBERS', 'CSPP_GROUPS', 'ELA_COUNTRY_CEILING', 'ELA_FUNDING_GAP', 'ELA_MFI_CEILING', 'ESA_95_INSTR_CLASS_CSDB', 'ESA_95_SECTOR', 'ESA_2010_INSTR_CLASS_CSDB', 'ESA_2010_ISSUER_CLASS_CSDB', 
    'ESAST_SUB_SECTOR_RIAD', 'HAIRCUT_CATEGORIES', 'HAIRCUT_SCHEDULE', 'HOLIDAY', 'INSTITUTION_C2D', 'INSTITUTION_ECONOMIC_ACTIVITY', 'INSTITUTION_IDENTIFIER_TYPE', 'INSTITUTION_RAT_OUTLOOK_VALUE', 'INSTITUTION_RAT_WATCH_VALUE', 'INSTITUTION_SUBROLE', 
    'ISSUER_DEBTOR_GUARANTOR_GROUP', 'LIMIT_BREACH_CAUSE', 'LIMIT_TYPE', 'LIMIT_VIOLATION_TYPE', 'MAP_COUPON_FREQ', 'MAP_COUPON_FREQ_RAR', 'MAP_COUPON_TYPE', 'MAP_COUPON_TYPE_RAR', 'NACE2_INDUSTRY_CLASS_CSDB', 'OPERATION_NAME', 
    'OPERATION_PROCEDURE', 'OPERATION_PUBLIC', 'OPERATION_TYPE', 'OWN_USE', 'PRICE_TYPE_MAP', 'PRICE_TYPE_RAR', 'PSE_TYPE', 'RATING_ACTION', 'RATING_PD', 'RATING_PRIORITY', 
    'RATING_SOURCE', 'RATING_TYPE', 'REDEMPTION_FREQUENCY_CSDB', 'REDEMPTION_TYPE_CSDB', 'TMS_POSITION_CONFIG', 'MARKET_COUNTRIES', 'MEASUREMENT_UNITS', 'NCB', 'PORTFOLIO', 'PP_BUCKET', 
    'PP_CASH_FLOW_TYPE', 'PP_METHOD', 'PP_PORTF_BNCHMK_MAP', 'SCENARIOS', 'INSTITUTION_CODE_TYPE', 'QUOT_BASIS_MAP', 'RATING', 'RIC_CODE_CREATION_RULE' 
    ) 
    ORDER BY TABLE_NAME
  ) LOOP
    SELECT 
    'INSERT INTO '||t.owner||'.'||t.table_name||'('||
    LISTAGG(t.column_name, ', ') WITHIN GROUP (ORDER BY t.column_id) ||')
    VALUES (' ||LISTAGG(DECODE(t.column_name, 'A_VALID_FROM', 'v_current_date', 'A_VALID_TO', 'v_future_date', DECODE(r.column_name, NULL, 'NULL', ':new.'||t.column_name)), ', ') WITHIN GROUP (ORDER BY t.column_id) ||')' AS v_ins_str,
    'UPDATE '||t.owner||'.'||t.table_name||' SET
      A_VALID_TO = v_current_date
    WHERE  
        1 = 1 
'||LISTAGG(DECODE(r.column_name, NULL, '', '    AND DECODE('||t.column_name|| ', :old.'||t.column_name||', 1, 0) = 1'||chr(13))) WITHIN GROUP (ORDER BY t.column_id) || '    AND A_VALID_TO = v_future_date'||chr(13) AS v_upd_str 
    INTO v_ins_str, v_upd_str
    FROM dba_tab_columns t, dba_tab_columns r
    WHERE
        t.owner = 'DW_REF_MAIN'
    AND t.table_name = i.TABLE_NAME
    AND 'OU_REF' = r.owner (+)
    AND t.table_name = r.table_name (+) 
    AND t.column_name = r.column_name (+)
    GROUP BY t.owner, t.table_name
    ;

    v_ref_table_name := i.OWNER||'.'||i.TABLE_NAME;
    v_trigger_name := i.OWNER||'.'||i.TABLE_NAME||'_H';

    v_trigger_sql := '
create or replace TRIGGER '||v_trigger_name||'
BEFORE INSERT OR UPDATE OR DELETE ON '||v_ref_table_name||'
REFERENCING NEW AS new OLD AS old
FOR EACH ROW
DECLARE
  v_current_date DATE := SYSDATE;
  v_future_date DATE  := TO_DATE(''31/12/9999'', ''DD/MM/YYYY'');
BEGIN
  IF INSERTING THEN
    '||v_ins_str||';
  ELSIF DELETING THEN
    '||v_upd_str||'  ;
  ELSIF UPDATING THEN
    '||v_upd_str||'  ;
    '||v_ins_str||';
  END IF;
END;';
   
  DBMS_OUTPUT.PUT_LINE(v_trigger_name); 
  EXECUTE IMMEDIATE v_trigger_sql;
--  DBMS_OUTPUT.PUT_LINE(v_trigger_sql||'
--/
--  ');

END LOOP;

END;
/






