HP 3000 Manuals

Locating Constraint Errors [ ALLBASE/SQL Release F.0 Application Programming Bulletin for MPE/iX ] MPE/iX 5.0 Documentation


ALLBASE/SQL Release F.0 Application Programming Bulletin for MPE/iX

Locating Constraint Errors 

When your transaction defers constraint checking, you can minimize the
possibility of rollback due to constraint errors by setting constraint
checking to IMMEDIATE just before the COMMIT WORK statement is executed.
Then check sqlcode for constraint errors.  If errors were encountered,
either prompt the user to make corrections or use the trouble shooting
templates below to locate the errors.  Once all errors have been
corrected, issue a COMMIT WORK statement.  The "Coding with Deferred
Constraint Error Checking" section provides an additional example. 

Template for Single Column Unique Constraint Errors 

This template returns the values in rows where a unique value in a single
column unique constraint or unique index is duplicated:

           SELECT UniqueColumn
             FROM UniqueTable
         GROUP BY UniqueColumn
     HAVING COUNT (UniqueColumn) > 1

Template for Multiple Column Unique Constraint Errors 

This template returns the values in rows where unique values are
duplicated in a multiple column unique constraint or unique index having
n columns:

           SELECT UniqueColumn1, UniqueColumn2, ..., UniqueColumnn 
             FROM UniqueTable
         GROUP BY UniqueColumn1, UniqueColumn2, ..., UniqueColumnn 
     HAVING COUNT (UniqueColumn1) > 1
        AND COUNT (UniqueColumn2) > 1
         :
        AND COUNT (UniqueColumnn) > 1

Template for Single Column Referential Constraint Errors 

This template returns the values in rows where the referencing value in a
single referencing column matches no referenced value:

               SELECT ForeignKeyColumn
                 FROM ForeignKeyTable
                WHERE ForeignKeyColumn IS NOT NULL
       AND NOT EXISTS (SELECT *
                         FROM PrimaryKeyTable
                        WHERE ForeignKeyColumn = PrimaryKeyColumn)

Template for Multiple Column Referential Constraint Errors 

This template returns the values in rows where the referencing values in
a multiple column referencial constraint with n columns match no
referenced values:

             SELECT ForeignKeyColumn1, ForeignKeyColumn2, ..., ForeignKeyColumnn 
               FROM ForeignKeyTable
              WHERE ForeignKeyColumn1 IS NOT NULL
                AND ForeignKeyColumn2 IS NOT NULL
                 :
                AND ForeignKeyColumnn IS NOT NULL
     AND NOT EXISTS (SELECT *
                       FROM PrimaryKeyTable
                      WHERE ForeignKeyColumn1 = PrimaryKeyColumn1
                        AND ForeignKeyColumn2 = PrimaryKeyColumn2
                         :
                        AND ForeignKeyColumnn = PrimaryKeyColumnn 

Coding with Deferred Constraint Error Checking 

Suppose the user wants to update information in the Clubs table and in
the Members table of RecDB. The Club column in the Members table
references the ClubName column in the Clubs table, and the ClubContact
column in the Clubs table references the MemberName column in the Members
table.  It is not possible to update both of these tables in the same
instant, and a referential constraint error could occur if one table is
modified and the other table is still unchanged.  In order to resolve
these circular referential constraints within the same transaction, you
can defer constraint error checking until the end of the transaction at
which point all constraints are resolved, as in the following example:
(Error checking is set to statement level, the default.)

     Execute subroutines to display and prompt for information needed in the Clubs table 
     and the Members table. 

     Place user entered data in appropriate host variables. 

     BEGIN WORK

     At this point you want to update the Clubs table.  However, ClubContact in the Clubs 
     table references MemberName in the Members table, and the Members table does not yet 
     have the appropriate primary key value inserted. 

     Defer referential error checking to the transaction level so that all constraints 
     in the transaction can be resolved before constraint errors are checked. 

      SET REFERENTIAL CONSTRAINTS DEFERRED 

       UPDATE RecDB.Clubs
          SET ClubName = :NewClubName :ClubNameInd,
              ClubPhone = :ClubPhone,
              Activity = :Activity,
              ClubContact = :ClubContact
        WHERE ClubName = :ClubName

                These indented statements are shown to illustrate 
                the warning issued when constraint checking is set 
                to a state at which it already exists and to show 
                what constraint errors would stop statement execution 
                if constraint checking had not been deferred. 

                 SET REFERENTIAL CONSTRAINTS DEFERRED 

                A warning is issued, since constraints are already deferred. 

                REFERENTIAL constraints already set to DEFERRED.  (DBWARN 2066)

                A referential constraint error occurs at this point.  If you 
                set constraints to IMMEDIATE, an error is issued saying that 
                there are one or more referential constraint errors, but 
                constraints stay deferred because the SET CONSTRAINTS 
                IMMEDIATE statement fails when outstanding constraint 
                errors exist. 

                 SET REFERENTIAL CONSTRAINTS IMMEDIATE 

                FOREIGN KEY constraint violated. (DBERR 2293)

                The sqlcode field of the sqlca equals -2293 because no primary 
                key exists for the foreign key ClubContact.  Constraint 
                checking remains deferred. 

     Resolve the unsatisfied constraints by inserting the necessary primary 
     keys in the Members table. 

     INSERT INTO RecDB.Members
        VALUES MemberName = :MemberName,
               Club = :Club,
               MemberPhone = :MemberPhone :MemberPhoneInd

     Set constraint error checking to IMMEDIATE.  If the SET CONSTRAINTS IMMEDIATE 
     statement succeeds, constraints are set to IMMEDIATE. If the SET CONSTRAINTS 
     IMMEDIATE statement fails because of constraint errors, constraints remain 
     deferred.  No rollback occurs. 

      SET REFERENTIAL CONSTRAINTS IMMEDIATE 

     Check the sqlcode field of the sqlca.  If constraint errors exist, you could code 
     statements that locate them, (See the templates in the previous section.) or you could 
     prompt the user for input to correct the errors. 

     When all constraint errors are resolved, commit the transaction. 

     COMMIT WORK

     If sqlcode is negative, the transaction is rolled back.  Inform the user. 
     For example, if sqlcode equals -2293, indicating no primary key match, display the 
     error message and prompt the user to indicate whether or not to insert a new 
     MemberName/Club primary key in the Members table or a new ClubName primary 
     key in the Clubs table or to exit the transaction.  Execute the appropriate subroutine. 

     Else, if sqlcode = 0, tell the user the transaction was successfully completed, and 
     prompt for additional information for the Clubs and Members tables or a return to 
     the main menu display. 



MPE/iX 5.0 Documentation