REM Program: keyreseq.sql

REM Author : David Wendelken

REM          Tactics, Inc.  (404) 248-1226

REM          Part of the Tactics' Designer/2000 Toolbox

REM Genesis: 26-Nov-1995

REM

REM Purpose: To make sure that primary, unique and foreign key constraint component

REM          columns are sequenced from 1 to N on a per constraint basis.  It is an

REM          enabling program for the d2pkchk.sql and d2fkchk.sql utilities.

REM Warning: Do not run this if others are the above mentioned constraintsin the 

REM          same application.

REM Warning: If you have duplicate sequence numbers for columns in a key constraint,

REM          they will be resequenced.  Naturally, this means that one will follow 

REM          the other.  Garbage In, Garbage Out!



PROMPT Enter the Application System Name

DEFINE p_application_system_name='&1'

PROMPT Enter the Application System Version

DEFINE p_application_system_version='&2'

PROMPT Enter Table Name or % for ALL

DEFINE p_table_name='&3'

PROMPT Enter the output filename (with the pathname but without the .lis extension)

DEFINE p_filename='&6'



set linesize  80

set pagesize  66

REM Let's not clutter up the screen and page with program code.

REM set verify   off

REM set echo     off

REM set feedback off



REM Force diagnostic output on so that the user can see what progress

REM          is being made and what the program did.



REM Adjust buffer size up or down as needed.

SET SERVEROUTPUT ON SIZE 50000

SPOOL &p_filename..lis



DECLARE -- resequence key component columns.

  cannot_init_appsys   EXCEPTION;        -- Application not available or no access.

  next_sequence_number ci_key_components.sequence_number%TYPE;

  last_constraint_id   ci_constraints.id%TYPE;



-- A cursor that will return 1 row per column that participates in a key constraint.

  CURSOR find_kc_columns IS

  SELECT  cicon.id               constraint_id

         ,cikeyc.id              key_component_id

         ,cikeyc.sequence_number key_component_sequence_number

         ,citabd.name            table_name

         ,cicon.name             constraint_name

  FROM    ci_key_components      cikeyc

         ,ci_constraints         cicon

         ,ci_table_definitions   citabd

         ,ci_application_systems ciapps

  WHERE   citabd.name    LIKE UPPER('&p_table_name')

    AND   citabd.id      =    cicon.table_reference

    AND   cicon.id       =    cikeyc.constraint_reference

    AND   ciapps.id      =    citabd.application_system_owned_by

    AND   ciapps.name    =    UPPER('&p_application_system_name')

    AND   ciapps.version =    &p_application_system_version

  ORDER BY citabd.name, cicon.name, cikeyc.sequence_number;



/************* Inline Procedure ***********************************/

PROCEDURE update_kc_sequence_number

(p_kc_id              IN  NUMBER

,p_kc_sequence_number IN  NUMBER

) IS



kc_to_update        ciokey_component.data;

activity_status     VARCHAR2(1);

activity_warning    VARCHAR2(1);



BEGIN

  -- Open an activity

  -- This issues a savepoint, so incomplete changes can be rolled back to here.

  CDAPI.OPEN_ACTIVITY;

  -- We update regardless of whether the old and new sequence numbers are equal.



  -- Set key component values and their indicators.

  kc_to_update.v.sequence_number := p_kc_sequence_number;

  kc_to_update.i.sequence_number := true;

  -- Update the key component record.

  CIOKEY_COMPONENT.UPD(p_kc_id, kc_to_update);

  -- Validate the key component update.

  CDAPI.VALIDATE_ACTIVITY(activity_status, activity_warning);

  -- Show violation messages here.

  FOR each_violation IN (SELECT * FROM ci_violations) 

  LOOP

    DBMS_OUTPUT.PUT_LINE(CDAPI.INSTANTIATE_MESSAGE(each_violation.facility

                                                  ,each_violation.code

                                                  ,each_violation.p0

                                                  ,each_violation.p1

                                                  ,each_violation.p2

                                                  ,each_violation.p3

                                                  ,each_violation.p4

                                                  ,each_violation.p5

                                                  ,each_violation.p6

                                                  ,each_violation.p7

                                                  )

                        );

  END LOOP;

  -- Attempt to close the activity.

  CDAPI.CLOSE_ACTIVITY(activity_status);

  -- If activity did not close, then abort and roll back changes.

  IF activity_status != 'Y' THEN

     CDAPI.ABORT_ACTIVITY;   

  END IF;

END;

/************* End of Inline Procedure ****************************/



/****************** Main Program ********************/

BEGIN

  BEGIN

    -- Initialize the Designer/2000 API.

    IF NOT cdapi.initialized THEN

       -- Not already initialized.

       CDAPI.INITIALIZE(UPPER('&p_application_system_name'),&p_application_system_version);

    END IF;

  EXCEPTION 

    WHEN OTHERS THEN 

      RAISE cannot_init_appsys;

  END;

  -- Fetch specified attributes 

  FOR kc_record IN find_kc_columns

  LOOP

    IF last_constraint_id IS NULL

    OR last_constraint_id != kc_record.constraint_id THEN

       last_constraint_id := kc_record.constraint_id;

       next_sequence_number := 1;

       DBMS_OUTPUT.PUT_LINE('Table     : ' || kc_record.table_name );

       DBMS_OUTPUT.PUT_LINE('Constraint: ' || kc_record.constraint_name );

    ELSE

       next_sequence_number := next_sequence_number + 1;

    END IF;

    DBMS_OUTPUT.PUT_LINE('Old Seq.  : ' || kc_record.key_component_sequence_number);

    DBMS_OUTPUT.PUT_LINE('New Seq.  : ' || next_sequence_number);

    UPDATE_KC_SEQUENCE_NUMBER(kc_record.key_component_id, next_sequence_number);

  END LOOP;

  -- All changes made.

  DBMS_OUTPUT.PUT_LINE('DONE');

EXCEPTION

  WHEN cannot_init_appsys THEN

    DBMS_OUTPUT.PUT_LINE('ERROR: Cannot Initialize API for the Application System: '

                          || UPPER('&p_application_system_name')

                        );

    DBMS_OUTPUT.PUT_LINE('_______Procedure aborted with errors!');

  WHEN OTHERS THEN

    DBMS_OUTPUT.PUT_LINE('ERROR : ' || SQLCODE || ', ' || SQLERRM);

    DBMS_OUTPUT.PUT_LINE('_______Procedure aborted with errors!');

END;  -- resequence key component columns

/

/****************** End of Main Program ************************/



SPOOL OFF

