SET PATH *LIBL ; CREATE OR REPLACE FUNCTION SAILPOINT.ES_V2_CREATE_USER_PROFILE ( AUTHORIZATIONNAME VARCHAR(10) , TEXTDESCRIPTION VARCHAR(50) DEFAULT NULL , USERCLASSNAME VARCHAR(10) DEFAULT NULL , STATUS VARCHAR(10) DEFAULT NULL , SETPASSWORDTOEXPIRE VARCHAR(10) DEFAULT NULL , USEROWNER VARCHAR(10) DEFAULT NULL , GROUPPROFILENAME VARCHAR(10) DEFAULT NULL , ACCOUNTINGCODE VARCHAR(20) DEFAULT NULL , JOBDESCRIPTIONNAME VARCHAR(10) DEFAULT NULL , OUTPUTQUEUENAME VARCHAR(21) DEFAULT NULL , MESSAGEQUEUENAME VARCHAR(21) DEFAULT NULL , LIMITCAPABILITIES VARCHAR(10) DEFAULT NULL , SPECIALAUTHORITIESJSON VARCHAR(1024) DEFAULT NULL ) RETURNS CLOB(2147483647) LANGUAGE SQL SPECIFIC SAILPOINT.V2_ESICRTUSR NOT DETERMINISTIC MODIFIES SQL DATA CALLED ON NULL INPUT NOT FENCED SET OPTION ALWBLK = *ALLREAD , ALWCPYDTA = *OPTIMIZE , COMMIT = *NONE , DBGVIEW = *SOURCE , DECRESULT = (31, 31, 00) , DLYPRP = *NO , DYNDFTCOL = *NO , DYNUSRPRF = *OWNER , SRTSEQ = *HEX BEGIN DECLARE CMD_OUTPUT CLOB ( 64 K ) DEFAULT '' ; DECLARE CMD_STMT VARCHAR ( 2048 ) DEFAULT '' ; DECLARE ERROR_RESPONSE CLOB ( 2 G ) DEFAULT '' ; DECLARE SPECIALAUTHS VARCHAR ( 1000 ) ; -- Uniform error handler - returns pre-built error JSON DECLARE CONTINUE HANDLER FOR SQLSTATE '38001' RETURN ERROR_RESPONSE ; -- Handle QCMD exception (38501 = external routine error) DECLARE EXIT HANDLER FOR SQLSTATE '38501' RETURN JSON_OBJECT ( 'data' : JSON_ARRAY ( ) , 'errors' : JSON_ARRAY ( JSON_OBJECT ( 'status' : 409 , 'message' : 'User profile already exists or command failed' ) ) ) ; -- Convert JSON array to space-separated list IF SPECIALAUTHORITIESJSON IS NOT NULL THEN SET SPECIALAUTHS = ( SELECT LISTAGG ( TRIM ( FRAGMENT ) , ' ' ) FROM TABLE ( CISTOOLS . SPLIT_STRING ( REGEXP_REPLACE ( CAST ( SPECIALAUTHORITIESJSON AS VARCHAR ( 1000 ) CCSID 37 ) , '[\[|\]|\{|\}|\""|\,|\s+]' , ' ' ) , ' ' ) ) WHERE FRAGMENT <> '' AND FRAGMENT IS NOT NULL ) ; END IF ; -- Build the command SET CMD_STMT = 'CRTUSRPRF USRPRF(' || TRIM ( AUTHORIZATIONNAME ) || ')' ; IF TEXTDESCRIPTION IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' TEXT(' || CISTOOLS . GET_QUOTED ( TEXTDESCRIPTION ) || ')' ; END IF ; IF USERCLASSNAME IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' USRCLS(' || USERCLASSNAME || ')' ; END IF ; IF STATUS IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' STATUS(' || STATUS || ')' ; END IF ; IF SETPASSWORDTOEXPIRE IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' PWDEXP(' || SETPASSWORDTOEXPIRE || ')' ; END IF ; IF USEROWNER IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' OWNER(' || USEROWNER || ')' ; END IF ; IF GROUPPROFILENAME IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' GRPPRF(' || GROUPPROFILENAME || ')' ; END IF ; IF ACCOUNTINGCODE IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' ACGCDE(' || ACCOUNTINGCODE || ')' ; END IF ; IF JOBDESCRIPTIONNAME IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' JOBD(' || JOBDESCRIPTIONNAME || ')' ; END IF ; IF OUTPUTQUEUENAME IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' OUTQ(' || OUTPUTQUEUENAME || ')' ; END IF ; IF MESSAGEQUEUENAME IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' MSGQ(' || MESSAGEQUEUENAME || ')' ; END IF ; IF LIMITCAPABILITIES IS NOT NULL THEN SET CMD_STMT = CMD_STMT || ' LMTCPB(' || LIMITCAPABILITIES || ')' ; ELSE SET CMD_STMT = CMD_STMT || ' LMTCPB(*YES)' ; END IF ; IF SPECIALAUTHS IS NOT NULL AND LENGTH ( TRIM ( SPECIALAUTHS ) ) > 0 THEN SET CMD_STMT = CMD_STMT || ' SPCAUT(' || SPECIALAUTHS || ')' ; END IF ; -- Execute via QCMD and capture output SET CMD_OUTPUT = CISTOOLS . QCMD ( CMD_STMT ) ; -- Check if any CPF/CPD errors exist (CPF=failure, CPD=diagnostic, CPC=completio--n/success) IF CMD_OUTPUT LIKE '%CPF%' OR CMD_OUTPUT LIKE '%CPD%' THEN -- Build errors array from all error lines in output SET ERROR_RESPONSE = ( SELECT JSON_OBJECT ( 'data' : JSON_ARRAY ( ) , 'errors' : JSON_ARRAYAGG ( JSON_OBJECT ( 'status' : CASE WHEN FRAGMENT LIKE '%CPF2214%' THEN 409 WHEN FRAGMENT LIKE '%CPF2213%' THEN 403 WHEN FRAGMENT LIKE '%CPF2225%' THEN 403 WHEN FRAGMENT LIKE '%CPF2203%' THEN 404 WHEN FRAGMENT LIKE '%CPF2209%' THEN 404 WHEN FRAGMENT LIKE '%CPF2283%' THEN 400 ELSE 500 END , 'message' : CASE WHEN FRAGMENT LIKE '%CPF2214%' THEN 'User profile already exists' WHEN FRAGMENT LIKE '%CPF2213%' THEN 'Not authorized to create user profiles' WHEN FRAGMENT LIKE '%CPF2225%' THEN '*SECADM required to create or change user profiles' WHEN FRAGMENT LIKE '%CPF2203%' THEN 'Group profile not found' WHEN FRAGMENT LIKE '%CPF2209%' THEN 'Library not found' WHEN FRAGMENT LIKE '%CPF2283%' THEN 'Maximum storage value not valid' ELSE TRIM ( FRAGMENT ) END ) ) ) FROM TABLE ( CISTOOLS . SPLIT_STRING ( CMD_OUTPUT , X'25' ) ) AS T WHERE FRAGMENT LIKE '%CPF%' OR FRAGMENT LIKE '%CPD%' ) ; SIGNAL SQLSTATE '38001' ; END IF ; -- Success - return user info with specialAuthorities as array RETURN ( SELECT JSON_OBJECT ( 'data' : JSON_ARRAY ( JSON_OBJECT ( 'authorizationName' VALUE CAST ( AUTHORIZATION_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 'tempPassword' VALUE CAST ( AUTHORIZATION_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 'textDescription' VALUE CAST ( TEXT_DESCRIPTION AS VARCHAR ( 256 ) CCSID 37 ) , 'userClassName' VALUE CAST ( USER_CLASS_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 'status' VALUE CAST ( STATUS AS VARCHAR ( 256 ) CCSID 37 ) , 'userOwner' VALUE CAST ( USER_OWNER AS VARCHAR ( 256 ) CCSID 37 ) , 'groupProfileName' VALUE CAST ( GROUP_PROFILE_NAME AS VARCHAR ( 256 ) CCSID 37 ) , 'accountingCode' VALUE CAST ( ACCOUNTING_CODE AS VARCHAR ( 256 ) CCSID 37 ) , 'homeDirectory' VALUE CAST ( HOME_DIRECTORY AS VARCHAR ( 256 ) CCSID 37 ) , 'limitCapabilities' VALUE CAST ( LIMIT_CAPABILITIES AS VARCHAR ( 528 ) CCSID 37 ) , 'specialAuthorities' VALUE ( SELECT JSON_ARRAYAGG ( TRIM ( FRAGMENT ) ) FROM TABLE ( CISTOOLS . SPLIT_STRING ( TRIM ( CAST ( A . SPECIAL_AUTHORITIES AS VARCHAR ( 528 ) CCSID 37 ) ) , ' ' ) ) WHERE TRIM ( FRAGMENT ) <> '' ) , 'creationTimestamp' VALUE CREATION_TIMESTAMP ) ) , 'errors' : JSON_ARRAY ( ) ) FROM QSYS2 . USER_INFO A WHERE AUTHORIZATION_NAME = UPPER ( AUTHORIZATIONNAME ) ) ; END ; GRANT ALTER , EXECUTE ON SPECIFIC FUNCTION SAILPOINT.V2_ESICRTUSR TO AMAPICS WITH GRANT OPTION ; GRANT EXECUTE ON SPECIFIC FUNCTION SAILPOINT.V2_ESICRTUSR TO PUBLIC ;