Friday, December 09, 2011

Oracle PL/SQL Stored Procedure Looping Nested Exception Handling

Today we have a requirement that we want to have a stored procedure loop an Oracle records, inside the loop, we want to insert each record into few more tables via sub stored procedure, but we want to continue the loop if the insertion fail, and just only rollback the fail insert for the particular record, let's see an example:-

We have Main table having Product ID 1 to 3, we will loop these records and insert each record into Table 1 and Table 2, i.e.
Loop for Product ID 1 - Insert Product ID 1 to table 1 success, Insert Product ID 1 to table 2 success;
Loop for Product ID 2 - Insert Product ID 2 to table 1 success, Insert Product ID 2 to table 2 fail;
Loop for Product ID 3 - Insert Product ID 3 to table 1 success, Insert Product ID 3 to table 2 success;

The tricky part is - we want to rollback the inserting Product ID 2 to table 1 and record the exception of inserting Product ID 2 to table 2 into Error Log and continue the next looping;

How we design the Exception Handling to handle this requirement?


The solution is we need to handle the exception within looping, in main loop, we should commit the transaction for each record's sub-transactions success, and ignore/rollback when any record sub-transaction is failure, and the logging of the exception should do it in sub transaction.

Here is the main stored procedure and sub stored procedures to simulate this scenario:-

PACKAGE BODY "YB_TEST" IS
PROCEDURE "PROC_MAIN" IS
BEGIN -- executable part starts here
    DECLARE CURSOR P IS
        SELECT PRODUCT_ID, PRODUCT_NAME
        FROM TABLE_LOOP
        ORDER BY PRODUCT_ID;

    BEGIN

        FOR r IN p LOOP
        BEGIN
            PROC_SUB1(r.PRODUCT_ID, r.PRODUCT_ID, 'REMARK FOR ' || r.PRODUCT_ID);
            PROC_SUB2(r.PRODUCT_ID, r.PRODUCT_ID, 'AUDIT FOR ' || r.PRODUCT_ID);
            COMMIT;
        EXCEPTION
          WHEN OTHERS
          THEN
             NULL;
--             ROLLBACK;
        END;
        END LOOP;
    END;
END "PROC_MAIN";

PROCEDURE "PROC_SUB1" (
  P_ORDER_ID IN NUMBER,
  P_PRODUCT_ID IN NUMBER,
  P_REMARKS IN VARCHAR2) IS
BEGIN -- executable part starts here

    INSERT INTO TABLE1 (ORDER_ID, PRODUCT_ID, REMARKS)
    VALUES (P_ORDER_ID, P_PRODUCT_ID, P_REMARKS);

    EXCEPTION
    WHEN OTHERS
    THEN
             ROLLBACK; -- Rollback the previous insert
             INSERT INTO TABLE_LOG (PRODUCT_ID, EXCEPTION_DESC)
             VALUES(P_PRODUCT_ID, SUBSTR(DBMS_UTILITY.FORMAT_ERROR_STACK, 1, 100));
             COMMIT; -- Commit this exception logging
             RAISE; -- Re-throw Exception to caller, i.e. Main Loop

END "PROC_SUB1";

PROCEDURE "PROC_SUB2" (
  P_AUDIT_ID IN NUMBER,
  P_PRODUCT_ID IN NUMBER,
  P_AUDIT_DESC IN VARCHAR2) IS
BEGIN -- executable part starts here

    INSERT INTO TABLE2 (AUDIT_ID, PRODUCT_ID, AUDIT_DESC)
    VALUES (P_AUDIT_ID, P_PRODUCT_ID, P_AUDIT_DESC);

    EXCEPTION
    WHEN OTHERS
    THEN
             ROLLBACK; -- Rollback the previous insert
             INSERT INTO TABLE_LOG (PRODUCT_ID, EXCEPTION_DESC)
             VALUES(P_PRODUCT_ID, SUBSTR(DBMS_UTILITY.FORMAT_ERROR_STACK, 1, 100));
             COMMIT; -- Commit this exception logging

             RAISE; -- Re-throw Exception to caller, i.e. Main Loop



END "PROC_SUB2";
END "YB_TEST";

Friday, November 11, 2011

SharePoint 2010 SharePoint Designer (50354B) Lab

To do the lab in SharePoint 2010 SharePoint Designer course 50354B, we can reuse other SharePoint courses Hyper-V image (e.g. SharePoint 2010 Application Development 10175) with the following configuration:-
  1. Enabled Desktop Experience in Windows 2008 R2 to enable MS Word documents save into SharePoint directly
  2. All http://Servername:100 change to http://SharePoint
  3. Setup http://SharePoint:112 for Publishing Portal
  4. SQL Server 2008 R2 need to enable SQL Server Authentication
  5. SQL Server sa user status should be enabled and configure password
  6. Install Northwind Database
  7. Module 4 Lab 1 Task 6 to join 2 data sources has bug in step 16 and require to fix the XSLT by following this article
  8. No SMTP setup is required
  9. Module 6 Lab 1 Step 17 (pg 20 of 27) should change "Send Email" to "Log to History"
  10. Module 6 Lab 2 Task 7 Step 3 (pg 3 of 6) should change Lookup Manager to Set Variable "manager" to SHAREPOINT\Administrator
  11. Module 6 Lab 2 Task 10 Step 8 (pg 5 of 6) Contose\sp_member change to Home Members
  12. Module 6 Lab 3 (pg 3 of 3) last step, the recursive workflow will stop by creating another announcement items and the exception will be log into C:\Program Files\Common Files\Microsoft Shared\Web Server Extension\14\Logs
  13. Module 6 Lab 4 (pg 6 0f 7), before import, we need to delete the workflow Anywhere from Site Setting->Site Admin->Workflow Settings
  14. Module 6 Lab 5 (pg 2 of 3) Step 14 is applied to Single Task not Overall Tasks
There is one mystery, the comment created from Workflow cannot be found from SharePoint.

Wednesday, November 09, 2011

SharePoint Designer 2010 Data View bug in Join Linked Data Source!

I have 2 Data Sources - Category and Product, I created a Linked Data Source to join these 2 tables using their common key, and created a Data View to access this Linked Data Source, unfortunately the Data View display only the blank data view but with the number of records correct which I can see it from the paging info.


Finally I found out there is a XSLT bug in SharePoint Designer 2010 after spending sometime to troubleshoot this funny problem:-


The node is selecting the wrong data source value, we can erase the data source value inside this node and use XPath Expression Builder to find out the actual data source value.


After correcting the data source value by using XSLT Expression Builder, my data view work like charm!

Saturday, October 29, 2011

SharePoint Wiki Link

SharePoint 2010 Wiki Link is powerful! We can create SharePoint Wiki Link by using [[Square Brackets]]

To link to your Wiki Page, type [[Wiki Page Name]], e.g. [[SharePoint]], it will be linked if the Wiki Page is exists else the Wiki Page will be created.


We also can link to any documents or lists using [[List:Path to the list item]], e.g. We have a video clip abc.wmv in Shared Documents, we can link it using [[List:Shared Documents/abc.wmv]]
You also can link to View using [[View:View Path]]

This feature is enabled in Site Settings/Features/Wiki Page Home Page.

Saturday, July 09, 2011

C# Batch Replace with encoding

Here is the code I wrote for batch replace with GB2312 encoding:-

var dir = new DirectoryInfo(@"D:\hgb");
string strFileName;
string content;
var encoding = Encoding.GetEncoding(936);

foreach (var f in dir.GetFiles("*.htm", SearchOption.AllDirectories))
{
strFileName = f.DirectoryName + @"\" + f.Name;
using (StreamReader reader = new StreamReader(strFileName, encoding))
{
content = reader.ReadToEnd();
content = Regex.Replace(content, "font size=-1", "font size=48");
}




StreamWriter writer = new StreamWriter(strFileName, false, encoding);
writer.Write(content);
writer.Close();
}

Thursday, July 07, 2011

10175 Lab Correction (SharePoint 2010 Application Development)

General
  1. Trainer MOC page number may different with student page number.

Lab 2


  1. There are spacing issues in Exercise 3 Task 4 PowerShell Commands, All *SP Solution commands should be corrected as *SPSolution, e.g. Add-SP Solution should be corrected as Add-SPSolution.
  2. The -GAC Deployment should be corrected as -GACDeployment

Lab 4
  1. We should remove the where clause in unfilteredJobs LINQ query from Exercise 3 Task 5 Step 12 then only step 21 All Jobs will be displayed correctly.
Lab 5
  1. The web.config never changed although the lab works as expected, this issue is caused by access denied, we have to fix it in Powershell:
    $svc = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
    $svc.RemoteAdministratorAccessDenied = $False
    $svc.Update()
  2. We should reference to System.Configuration to use the ConfigurationManager in Exercise 3 Task 2 Step 2.
Lab 6
  1. When you are instructed to input any object or variable name with spacing, please remove the space, example:- HR Training Management has to be input as HRTrainingManagement.

Lab 8
  1. There is a list "Mashup" is hidden, we can display it from SharePoint Designer All Files section.

Lab 10
  1. Please create a site page named Training for Exercise 2 Task 9 Step 3
  2. You may need to click the Share Documents few times to let the video thumbnails to display accordingly.
Lab 13
  1. The Microsoft Office is not activated in Hyper-V image and not able to perform Exercise 2 Task 1, workaround is to copy the Metro theme from C:\Program Files (x86)\Microsoft Office\Document Themes 14\Metro.thmx to Desktop

Monday, February 28, 2011

Unsubscribe Tweeter from Maxis

Recently test with Tweeter to try out Mobile notification, after testing try to unsubscribe but failed few times by sms STOP to 28933 Maxis Tweet2Me service.

Finally I can unsubscribed successfully by using this command:-

STOP TWEET2ME to 28933.

Receive the response from Maxis:-
RM0. Your Twitter SMS subscription has been terminated.

Wednesday, January 12, 2011

Javascript getElementByTagName XML with namespace prefix

How to use Javascript to retrieve XML data with namespace prefix?

Example:-



We can use getElementByTagName together with namespace prefix to access the element value:-
xmlDoc.getElementsByTagName("ns0:POID")[0].firstChild.nodeValue ;

Whole code to access the XML data with namespace prefix via getElementsByTagName:-


<html><head>

<script language="javascript">

function getXML()

{

var xmlstring = "<?xml version='1.0' ?><ns0:PO xmlns:ns0='http://www.abc.com/PO'><ns0:POID>PO123</ns0:POID><ns0:CustomerID>ABC007</ns0:CustomerID></ns0:PO>";

if (window.DOMParser)

  {

  parser=new DOMParser();

  xmlDoc=parser.parseFromString(xmlstring,"text/xml");

  }

else // Internet Explorer

  {

  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");

  xmlDoc.async="false";

  xmlDoc.loadXML(xmlstring);

  }

var x = xmlDoc.getElementsByTagName("ns0:POID")[0].firstChild.nodeValue ;

alert(x);

}

</script>

</head><body onload="javascript:getXML()">

</body></html>

<?xml version='1.0' ?>
<ns0:PO xmlns:ns0='http://www.abc.com/PO'>
<ns0:POID>PO123</ns0:POID>
<ns0:CustomerID>ABC007</ns0:CustomerID>
</ns0:PO>