In recent project, we had an challenge in data intensive application design as Pega does not support distributed transaction with external databases.
After trying out several designs, we found an excellent solution which not only requires very less coding, but scalable, robust and more over fits perfectly given the nature of Pega Architecture and most of the RDBMS.
The one-line solution is XML!
Yes, since pega internally stores anything and everything as XML, we have an easy job when we can pass the complete work object (pega-terminalogy equivalent to object in java) in XML format to Database, where DB can parse the input, process and send back the reponse in same way.
PROCEDURE FRED_SERVICE (
p_header IN CLOB,
p_request IN CLOB,
p_response OUT VARCHAR2,
p_err_code OUT NUMBER
)
IS
/* XML Parsing local variables */
l_doc DBMS_XMLDOM.DOMDocument;
l_element DBMS_XMLDOM.DOMElement;
l_attr DBMS_XMLDOM.DOMAttr;
l_node DBMS_XMLDOM.DOMNode;
l_node_list DBMS_XMLDOM.DOMNodeList;
l_pxResults_list DBMS_XMLDOM.DOMNodeList;
l_rowdata_list DBMS_XMLDOM.DOMNodeList;
l_rowdata_child_list DBMS_XMLDOM.DOMNodeList;
l_node_value VARCHAR2(1000);
l_tag_name VARCHAR2(1000);
l_pxResults_size NUMBER;
l_rowdata_size NUMBER;
l_rowdata_child_size NUMBER;
l_rowdata_column FRED_UTIL.FRED_ELEMENT := FRED_UTIL.FRED_ELEMENT('ELEMENT1',
'ELEMENT2',
'ELEMENT3',
'ELEMENT4',
'ELEMENT5');
l_rowdata_map FRED_UTIL.FRED_ELEMENT_MAP;
/* Transaction Unit local variables*/
ELEMENT1 NUMBER;
ELEMENT2 NUMBER;
ELEMENT3 NUMBER;
ELEMENT4 DATE;
ELEMENT5 VARCHAR2(3);
/* Trace */
l_file UTL_FILE.file_type;
l_log_file_name VARCHAR2 (100) := 'fredService.log';
l_log_dir VARCHAR2 (100) := '/tmp';
l_log_msg VARCHAR2 (1000) := 'fredService';
BEGIN
p_err_code :=0;
p_response :=NULL;
l_log_msg := TO_CHAR (SYSDATE, 'MM/DD/YY HH24:MI:SS')||'**** fred_service STARTED****';
l_log_msg := l_log_msg||chr(10);
DBMS_OUTPUT.put_line (l_log_msg);
l_file := UTL_FILE.fopen (l_log_dir,l_log_file_name,'W');
UTL_FILE.put_line (l_file,l_log_msg);
IF p_request IS NULL
THEN
p_err_code := 999;
p_response := 'INPUTNULL';
UTL_FILE.put_line (l_file,p_response);
ELSE
l_doc := DBMS_XMLDOM.newdomdocument (p_request);
l_pxResults_list := DBMS_XMLDOM.getelementsbytagname (l_doc, 'pxResults');
l_rowdata_list := DBMS_XMLDOM.getChildrenByTagName(DBMS_XMLDOM.makeElement(DBMS_XMLDOM.item(l_pxResults_list,0)),'rowdata');
l_rowdata_size := DBMS_XMLDOM.getlength (l_rowdata_list);
FOR rowCounter in 0..l_rowdata_size-1 LOOP
FOR colCounter in 1..l_rowdata_column.count LOOP
l_rowdata_child_list := DBMS_XMLDOM.getChildrenByTagName(DBMS_XMLDOM.makeElement(DBMS_XMLDOM.item(l_rowdata_list,rowCounter)),l_rowdata_column(colCounter));
l_node := DBMS_XMLDOM.item(l_rowdata_child_list,0);
l_rowdata_map(l_rowdata_column(colCounter)) := DBMS_XMLDOM.getNodeValue(DBMS_XMLDOM.getFirstChild(l_node));
END LOOP;
ELEMENT1 :=TO_NUMBER(l_rowdata_map('ELEMENT1'));
ELEMENT2 :=TO_NUMBER(l_rowdata_map('ELEMENT2'));
ELEMENT3 :=TO_NUMBER(l_rowdata_map('ELEMENT3'));
ELEMENT4 :=TO_DATE(SUBSTR(l_rowdata_map('ELEMENT4'),1,8),'YYYYMMDD');
ELEMENT5 :=l_rowdata_map('ELEMENT5');
l_log_msg := l_log_msg||'
'
||'Calling Business Transaction with following parameters'||'
'
||'ELEMENT1: '||ELEMENT1||'
'
||'ELEMENT2: '||ELEMENT2||'
'
||'ELEMENT3: '||ELEMENT3||'
'
||'ELEMENT4: '||ELEMENT4||'
'
||'ELEMENT5: '||ELEMENT5||'
';
END LOOP;
END IF;
l_log_msg := l_log_msg ||'
'||TO_CHAR (SYSDATE, 'MM/DD/YY HH24:MI:SS')||'**** fred_service completed****';
p_response := l_log_msg;
UTL_FILE.put_line (l_file,l_log_msg);
UTL_FILE.fclose (l_file);
EXCEPTION WHEN OTHERS THEN
p_err_code := SQLCODE;
p_response := SQLERRM;
END FRED_SERVICE;