Q: Wich constraint was violated (I4GL) ?
Posted in 1995
>
>
>
> Hi there,
>
> Is there a way in I-4GL to know wich CONSTRAINT has been violated (I don't
> want to place it in errorlog) ?
>
The following is an error routine that I modified from one of Peter
Botcherby's. It traps constraint errors and identifies the constraint which
failed (by text - not name). I'm not including the form in question - it's
a very simple form - one display field with 6 lines and wordwrap compress.
------
###############################################################################
#
# errlib.4gl : error library routines.
#
# Called by: N/A
#
# Syntax: N/A
#
# Dependencies: None.
#
# Calls: Nobody
#
# Returns: N/A
#
# Included routines:
#
# err_rtn() error handler
#
# ident_constr() identify constraint in error
#
# idx_parts() rebuild text of check constraint
#
#
{$Log: errlib.4gl,v $
Revision 1.2 95/05/26 16:54:29 16:54:29 jparker (Jack Parker)
corrected a typo in a comment which cause a compile failure.
Revision 1.1 95/05/26 15:21:29 15:21:29 jparker (Jack Parker)
Initial revision
}
#
###############################################################################
GLOBALS "dwglob.4gl"
# The above Includes:
# DEFINE logfle CHAR(80)
# DEFINE admin CHAR(80)
##############################################################################
# Routine : err_rtn
#
# Purpose : This function is called "WHENEVER ERROR" error is encountered
# It will record the error, notify the user and exit gracefully
#
# Arguments : none
#
# Returns : After constraint errors only.
##############################################################################
function err_rtn()
define sql_err smallint
define str char(255)
define ans char(1)
define strx char(80)
define errm char(80)
define cmd_string char(80)
define frm_title char(80)
define sql_stmt CHAR(400)
# logfle is defined in the globals. Supposedly also set on a program by
# program basis before it gets here. If it wasn't then we need to do
# something.
IF LENGTH(logfle) = 0 THEN
LET logfle = "/tmp/errmsg"
END IF
# admin was also set in set_glob() by each program. In case it wasn't...
IF LENGTH(admin) = 0 THEN
LET admin = "jparker@hpbs3645.boi.hp.com"
END IF
WHENEVER ERROR STOP #THIS MUST BE STOP - as it cannot call itself!!!
# retreive the error info
let sql_err = status
let errm = sqlca.sqlerrm
call err_get(sql_err) returning str
# format the error details into the error message
LET str=fmt_err(str, errm, "", "", "")
# tack on some extra info: program name
let strx = arg_val(0) # executable name
# version info on program
LET cmd_string = 'what ', strx clipped, '>> ', logfle clipped
RUN cmd_string
# who was running it.
LET cmd_string = 'logname >> ', logfle clipped
RUN cmd_string
# platform info
LET cmd_string = 'uname -a >> ', logfle clipped
RUN cmd_string
# program name report
let strx = "Error occured running: ", strx clipped
call errorlog(strx)
# close the error log and mail it.
let strx = "===END ERROR=^^==========================================="
call errorlog(strx)
LET cmd_string = 'mailx -s "Error Log" ' , admin clipped, '<',
logfle clipped
RUN cmd_string
# clear the error log.
LET cmd_string = 'cat /dev/null > ', logfle clipped
RUN cmd_string
# Display the error
open window w_err at 2,3 with FORM "dsp_msg"
attribute (border, prompt line last, form line first)
LET frm_title = " INFORMIX ERROR # ", sql_err
display frm_title TO formonly.title
display str TO formonly.msg
OPTIONS ACCEPT KEY ESC
# If it was a constraint, then which one.
if sql_err = -268
OR sql_err = -530
OR sql_err = -691 THEN
# ALLOW THEM TO GET MORE INFO ON CONSTRAINTS VIOLATED.
CALL ident_constr(SQLCA.SQLERRM) RETURNING sql_stmt
OPEN WINDOW w_cnst at 10,3 with FORM "dsp_msg"
attribute (border, prompt line last, form line first)
display "Constraint definition in violation" TO formonly.title
display sql_stmt TO formonly.msg
prompt "Press any key to continue ..." for char ans
close window w_cnst
close window w_err
OPTIONS ACCEPT KEY CONTROL-M
RETURN
# RETURN BECAUSE THIS IS A TRAPPED ERROR, NOT A FATAL, THE WHOLE
# POINT OF THIS EXERCISE IS SO THAT THEY CAN CORRECT THE PROBLEM
# WITHOUT LOSING THEIR WORK TO DATE.
end if
prompt "Press any key to continue ..." for char ans
close window w_err
OPTIONS ACCEPT KEY CONTROL-M
exit program 1
end function
#####################################################################
# This code comes to you grace au dbdiff. The intent of that program
# is to turn constraint info stored in the catalogues back into its
# original SQL. I have not gone through GREAT pains to change that
# bent. Therefore bear with it.
#####################################################################
# Tell the user more info on the constraint in question.
#####################################################################
FUNCTION ident_constr(constr_name)
DEFINE constr_rec RECORD
constr_id INTEGER,
constr_name CHAR(18),
owner CHAR(8),
tabid INTEGER,
constrtype CHAR(1),
idxname CHAR(18),
tabname CHAR(18),
primary INTEGER
END RECORD,
constr_name CHAR(20),
sql_stmt CHAR(500),
stmt1 CHAR(80),
i, j SMALLINT,
p_colname CHAR(18),
p_tabname CHAR(18),
col_strng CHAR(330) # 16*20+10_just_in_case
#####################################################################
# checks are separate
#####################################################################
# Split owner off of constraint name
LET j = LENGTH(constr_name)
FOR i = 1 TO LENGTH(constr_name)
IF constr_name[i,i] = "." THEN
LET i = i + 1
EXIT FOR
END IF
END FOR
LET constr_name = constr_name[i,j]
# display the constraint
SELECT sysconstraints.constrid, constrname,
sysconstraints.owner, sysconstraints.tabid, constrtype,
sysconstraints.idxname, tabname, primary
INTO constr_rec.*
FROM sysconstraints, systables, OUTER sysreferences
WHERE sysconstraints.tabid = systables.tabid
AND sysconstraints.constrid = sysreferences.constrid
#AND constrtype != 'C'