CC&B Business users enjoy sending requests to IT department regarding mass updates. Mass volume is something relative as it could be hundreds or could be millions of records. Recently I was requested to update around 3000 Service Agreements from "Active" Status to "Pending Stop" status as this number of records will take weeks from the Customer Service department to accomplish.
I had several options on the table:
Solution 1 (Quick Solution):
Directly update from the Database !!! This is the danger Zone as contractually with the vendor, if something goes wrong, we are toasted, NO SUPPORT will be provided.
Solution 2 (Not worth the effort):
Create a CC&B Java batch job to do it that will probably read from a flat file or a staging table and perform the job. This will take considerable effort and as its a one time job, it looks like its not worth it.
Solution 3 (The winning Card):
Write a small PL/SQL script that calls XAI service of "Start Stop" page. This a fast method to perform a one-time job such as this example.
Demo
In this post I will demonstrate how to loop for SA records and invoke the XAI directly from the Oracle Database using an anonymous PL/SQL block.
Assumption (No details will be provided on the basics of the below topics):
-You have the XAI service setup and running ( here I named the XAI service "CM_StartStopPageMaintenance")
-You know how the XML SOAP message looks like for the XAI service as it will be constructed in the PL/SQL script.
-You have basic PL/SQL knowledge, including the UTL_HTTP Oracle supplied package.
The following script will loop for all requires SA's and construct an XML message for each SA and invoke the XAI service to stop the SA
-------------------
-------------------
DECLARE
v_xml_message VARCHAR2 (4000);
v_acct_per_rec ci_acct_per%ROWTYPE;
v_acct_rec ci_acct%ROWTYPE;
vc_url VARCHAR2 (12) := '10.1.1.2'; --IP Address of the XAI server
ip_port VARCHAR2 (12) := '6500'; --Port of the CCB webserver
xai_directory VARCHAR2 (100) := 'XAIApp/xaiserver';
auth_id VARCHAR2 (100) := 'SYSUSER'; --User name to log into the XAI server
auth_pswd VARCHAR2 (100) := 'password01'; --Password
http_req UTL_HTTP.req;
http_resp UTL_HTTP.resp;
response_env_clob CLOB;
BEGIN
FOR ri IN (SELECT *
FROM ci_sa
WHERE sa_status_flg = '20'
AND (sa_id IN
('0000000968', '0000000059', '0000000260',
'0000000722', '0000000492', '0000000286',
'0000000302', '0000000321', '0000000083')
)) --to keep it simple I put only few dummy SA IDs
LOOP
SELECT *
INTO v_acct_per_rec
FROM ci_acct_per
WHERE acct_id = ri.acct_id AND main_cust_sw = 'Y';
SELECT *
INTO v_acct_rec
FROM ci_acct
WHERE acct_id = ri.acct_id;
--Construct the XML message that will passed to the XAI service from the current SA record values
v_xml_message :=
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="urn:schemas-xmlsoap-org:envelope">
<SOAP-ENV:Body>
<CM_StartStopPageMaintenance transactionType="CHNG">
<CM_StartStopPageMaintenanceService>
<CM_StartStopPageMaintenanceDetails AccountID="'
|| ri.acct_id
|| '" CurrencyCode="AED" StartDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" CodeTotalToBillAmount="0" STOPENDDT="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" StopMethod="SA" StopServiceagreementID="'
|| ri.sa_id
|| '" ACTIONSTARTSW="false" ACTIONSTOPSW="true" BUILDSTARTSASW="false" StartPremiseSPs="false" STARTSELECTSASW="false" ERRORCREATESASW="false" CREATESTARTFASW="true" CREATESTOPFASW="true" StopSelected="false" StopSelectedSA="false" ChangeStartStopDate="false" Reject="false" ScheduledFromDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" ScheduledToDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" StartStopDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" AccountID2="'
|| ri.acct_id
|| '" Address12="0" AddressLine4="" BillAddressSource="PER" BillRouteType="OUTSRC" Country="UAE" Version="" MainCustomerPersonID="'
|| v_acct_per_rec.per_id
|| '" BillAddressSrceFlg2="PER" BillRoutingMethod="P" MailingPremiseID="'
|| v_acct_rec.mailing_prem_id
|| '" MessageCategory="0" MessageNumber="0" PhoneCollFrDflt="Y" Country2="UAE" Address1Available="true" Address2Available="true" Address3Available="true" Address4Available="true" CityAvailable="true" Version2="" Number1Available="false" HouseTypeAvailable="false" CountyAvailable="true" StateAvailable="true" PostalAvailable="true" GeoCodeAvailable="false" Language="ENG" County="Abu Dhabi" State="AD" InCityLimit="false" CollTypeFlag="D" StartRecCnt="0" StopRecCnt="0" StopDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" Attrribute="Value">
<PendingStartStop />
</CM_StartStopPageMaintenanceDetails>
</CM_StartStopPageMaintenanceService>
</CM_StartStopPageMaintenance>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
UTL_HTTP.set_response_error_check (FALSE);
UTL_HTTP.set_transfer_timeout (60);
http_req :=
UTL_HTTP.begin_request ( 'http://'
|| vc_url
|| ':'
|| ip_port
|| '/'
|| xai_directory,
'POST',
UTL_HTTP.http_version_1_1
);
UTL_HTTP.set_authentication (http_req, auth_id, auth_pswd);
UTL_HTTP.set_header (http_req, 'Content-Type',
'text/xml; charset=utf-8');
UTL_HTTP.set_header (http_req, 'Content-Length', LENGTH (v_xml_message));
UTL_HTTP.write_text (http_req, v_xml_message);
http_resp := UTL_HTTP.get_response (http_req);
DECLARE
l_buffer_size NUMBER (10) := 512;
response_env BLOB;
BEGIN
LOOP
UTL_HTTP.read_raw (http_resp, response_env, l_buffer_size);
response_env_clob :=
response_env_clob || UTL_RAW.cast_to_varchar2 (response_env);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (http_resp);
END;
END LOOP;
END;
-------------------
-------------------
Note: I tested this script and all SA's were closed successfully on test environment, but in other more complicated cases, I would add exception handling and log the failed calls to study how to solve them.
Your comments are welcomed to enhance this post so that the benefit can be spread around ;)
DISCLAIMER: This information is provided "as is". The author of this information disclaim any loss or liability,
either directly or indirectly as a consequence of applying the information presented herein, or in regard to the use
and application of said information. No guarantee is given, either expressed or implied, in regard to the
merchantability, accuracy, or acceptability of the information
I had several options on the table:
Solution 1 (Quick Solution):
Directly update from the Database !!! This is the danger Zone as contractually with the vendor, if something goes wrong, we are toasted, NO SUPPORT will be provided.
Solution 2 (Not worth the effort):
Create a CC&B Java batch job to do it that will probably read from a flat file or a staging table and perform the job. This will take considerable effort and as its a one time job, it looks like its not worth it.
Solution 3 (The winning Card):
Write a small PL/SQL script that calls XAI service of "Start Stop" page. This a fast method to perform a one-time job such as this example.
Demo
In this post I will demonstrate how to loop for SA records and invoke the XAI directly from the Oracle Database using an anonymous PL/SQL block.
Assumption (No details will be provided on the basics of the below topics):
-You have the XAI service setup and running ( here I named the XAI service "CM_StartStopPageMaintenance")
-You know how the XML SOAP message looks like for the XAI service as it will be constructed in the PL/SQL script.
-You have basic PL/SQL knowledge, including the UTL_HTTP Oracle supplied package.
The following script will loop for all requires SA's and construct an XML message for each SA and invoke the XAI service to stop the SA
-------------------
-------------------
DECLARE
v_xml_message VARCHAR2 (4000);
v_acct_per_rec ci_acct_per%ROWTYPE;
v_acct_rec ci_acct%ROWTYPE;
vc_url VARCHAR2 (12) := '10.1.1.2'; --IP Address of the XAI server
ip_port VARCHAR2 (12) := '6500'; --Port of the CCB webserver
xai_directory VARCHAR2 (100) := 'XAIApp/xaiserver';
auth_id VARCHAR2 (100) := 'SYSUSER'; --User name to log into the XAI server
auth_pswd VARCHAR2 (100) := 'password01'; --Password
http_req UTL_HTTP.req;
http_resp UTL_HTTP.resp;
response_env_clob CLOB;
BEGIN
FOR ri IN (SELECT *
FROM ci_sa
WHERE sa_status_flg = '20'
AND (sa_id IN
('0000000968', '0000000059', '0000000260',
'0000000722', '0000000492', '0000000286',
'0000000302', '0000000321', '0000000083')
)) --to keep it simple I put only few dummy SA IDs
LOOP
SELECT *
INTO v_acct_per_rec
FROM ci_acct_per
WHERE acct_id = ri.acct_id AND main_cust_sw = 'Y';
SELECT *
INTO v_acct_rec
FROM ci_acct
WHERE acct_id = ri.acct_id;
--Construct the XML message that will passed to the XAI service from the current SA record values
v_xml_message :=
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="urn:schemas-xmlsoap-org:envelope">
<SOAP-ENV:Body>
<CM_StartStopPageMaintenance transactionType="CHNG">
<CM_StartStopPageMaintenanceService>
<CM_StartStopPageMaintenanceDetails AccountID="'
|| ri.acct_id
|| '" CurrencyCode="AED" StartDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" CodeTotalToBillAmount="0" STOPENDDT="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" StopMethod="SA" StopServiceagreementID="'
|| ri.sa_id
|| '" ACTIONSTARTSW="false" ACTIONSTOPSW="true" BUILDSTARTSASW="false" StartPremiseSPs="false" STARTSELECTSASW="false" ERRORCREATESASW="false" CREATESTARTFASW="true" CREATESTOPFASW="true" StopSelected="false" StopSelectedSA="false" ChangeStartStopDate="false" Reject="false" ScheduledFromDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" ScheduledToDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" StartStopDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" AccountID2="'
|| ri.acct_id
|| '" Address12="0" AddressLine4="" BillAddressSource="PER" BillRouteType="OUTSRC" Country="UAE" Version="" MainCustomerPersonID="'
|| v_acct_per_rec.per_id
|| '" BillAddressSrceFlg2="PER" BillRoutingMethod="P" MailingPremiseID="'
|| v_acct_rec.mailing_prem_id
|| '" MessageCategory="0" MessageNumber="0" PhoneCollFrDflt="Y" Country2="UAE" Address1Available="true" Address2Available="true" Address3Available="true" Address4Available="true" CityAvailable="true" Version2="" Number1Available="false" HouseTypeAvailable="false" CountyAvailable="true" StateAvailable="true" PostalAvailable="true" GeoCodeAvailable="false" Language="ENG" County="Abu Dhabi" State="AD" InCityLimit="false" CollTypeFlag="D" StartRecCnt="0" StopRecCnt="0" StopDate="'
|| TO_CHAR (SYSDATE, 'yyyy-mm-dd')
|| '" Attrribute="Value">
<PendingStartStop />
</CM_StartStopPageMaintenanceDetails>
</CM_StartStopPageMaintenanceService>
</CM_StartStopPageMaintenance>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
UTL_HTTP.set_response_error_check (FALSE);
UTL_HTTP.set_transfer_timeout (60);
http_req :=
UTL_HTTP.begin_request ( 'http://'
|| vc_url
|| ':'
|| ip_port
|| '/'
|| xai_directory,
'POST',
UTL_HTTP.http_version_1_1
);
UTL_HTTP.set_authentication (http_req, auth_id, auth_pswd);
UTL_HTTP.set_header (http_req, 'Content-Type',
'text/xml; charset=utf-8');
UTL_HTTP.set_header (http_req, 'Content-Length', LENGTH (v_xml_message));
UTL_HTTP.write_text (http_req, v_xml_message);
http_resp := UTL_HTTP.get_response (http_req);
DECLARE
l_buffer_size NUMBER (10) := 512;
response_env BLOB;
BEGIN
LOOP
UTL_HTTP.read_raw (http_resp, response_env, l_buffer_size);
response_env_clob :=
response_env_clob || UTL_RAW.cast_to_varchar2 (response_env);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (http_resp);
END;
END LOOP;
END;
-------------------
-------------------
Note: I tested this script and all SA's were closed successfully on test environment, but in other more complicated cases, I would add exception handling and log the failed calls to study how to solve them.
Your comments are welcomed to enhance this post so that the benefit can be spread around ;)