in

code for eternity !!!

community website for .net freaks ;-)

Technology

May 2008 - Posts

  • T-SQL Function to Get Int From Varchar

    I recently had to write a T-SQL function which cleans up all non numeric characters from a varchar variable and returns the int value of the remaining numeric characters. If no numeric characters exist, the function should return zero. I thought it would be nice to share this with you and I hope you find this useful ;-) Here is the function:

        CREATE FUNCTION [dbo].[GetIntFromVarchar]
        (
            @originalString varchar(50)
        )

        RETURNS int

        AS

        BEGIN

            -- declare local variable to hold numeric characters
            -- and assign default value of empty string
            DECLARE @retVal varchar(50)
            SET @retVal = ''

            -- declare local variable to loop through @originalString
            -- and assign initial value of 1
            DECLARE @loop int
            SET @loop = 1

            -- loop through every character in @originalString
            WHILE @loop <= LEN(@originalString)

                BEGIN
                   
                    IF ISNUMERIC(SUBSTRING(@originalString, @loop, 1)) = 1

                        BEGIN
                           
                            -- if numeric character found, append it to @retVal
                            SET @retVal = @retVal + SUBSTRING(@originalString, @loop, 1)

                        END

                    SET @loop = @loop + 1 -- increment value of @loop by 1

                END
           
            -- set @retVal to '0' if no numeric characters found
            IF @retVal = ''

                BEGIN

                    SET @retVal = '0'

                END
           
            -- return int value of numeric characters found
            -- by casting @retVal to int
            RETURN CAST(@retVal as int)

        END

    Once you have created this function, execute below T-SQL statements to verify the same:

        PRINT dbo.GetIntFromVarchar('R1A2J3') -- returns 123
        PRINT dbo.GetIntFromVarchar('COOL456CODER') -- returns 456
        PRINT dbo.GetIntFromVarchar('789') -- returns 789
        PRINT dbo.GetIntFromVarchar('GEEK') -- returns 0

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 20 2008, 11:48 AM by raj with 1 comment(s)
    Filed under:
  • Developers are Born Brave

    Reality about software development. Below image says it all ;-) Cheers to every coder reading this blog post :-) Please scroll to the right if you cannot see the entire image at 1 glance or click here to view / download the image in a seperate window.

    Developers are Born Brave

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 16 2008, 05:15 PM by raj with 8 comment(s)
    Filed under: ,
  • Coders versus Project Managers

    Few months back, I got below joke emailed to me by my friend who is also a passionate coder. In my personal (and humble) opinion, below joke hits jackpot with the current state of 9 out of 10 IT companies in India, which are headed by people who have zero or very little technical background. And perhaps this explains why Indian IT companies still have to market themselves as low cost outsourcing destinations to win business any why we still dont have too many Product based IT companies in India :-) Is the story same in your country too? Let me know, I would love to hear :-)

    Here is the joke, enjoy and forward this to all your coder friends ;-)

    A woman in a hot air balloon realized she was lost.

    She reduced altitude and spotted a man below. She descended a bit more and shouted, "Excuse me, can you help me? I promised a friend I would meet him an hour ago but I don't know where I am."

    The man below replied, "You're in a hot air balloon hovering approximately 30 feet above the ground. You're between 40 and 41 degrees north latitude and between 59 and 60 degrees west longitude."

    "You must be an engineer" said the balloonist.

    "I am", replied the man. "How did you know?"

    "Well", answered the balloonist, "everything you told me is technically correct, but I've no idea what to make of your information, and the fact is I'm still lost. Frankly, you've not been much help at all. If anything you've delayed my trip even more."

    The man below responded, "You must be in management."

    "I am," replied the balloonist, "but how did you know?"

    "Well", said the man, "You don't know where you are or where you're going. You have risen to where you are due to a large quantity of hot air. You made a promise which you've no idea how to keep, and you expect people beneath you to solve your problems"

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 14 2008, 11:15 AM by raj with 4 comment(s)
    Filed under: ,
  • LINQ Single and SingleOrDefault

    We can use the Single extension method of LINQ to return the only element in a sequence that satisfies a specified condition. However the Single extension method would throw the System.InvalidOperationException when no element in a sequence satisfies a specified condition. In such a scenario, we can use the SingleOrDefault extenion method which would return the default value of a type instead of throwing the System.InvalidOperationException.

    Also, both Single as well as SingleOrDefault extension methods would throw the System.InvalidOperationException when more than one element in a sequence satisfy a specified condition. We can use First or Last extensions methods of LINQ in such scenarios.

    Code example (both in C# and VB.NET) with comments below:

    C#:

        // Create a new generic list of ints
        List<int> l = new List<int>();

        l.Add(1); // Add 1 to the list
        l.Add(5); // Add 5 to the list
        l.Add(3); // Add 3 to the list

        // Returns 1 as only 1 satisfies the condition
        int value = l.Single(i => i == 1);

        // Returns the default value of int which is 0
        // since no element in the list equals 4
        value = l.SingleOrDefault(i => i == 4);

        // Throws System.InvalidOperationException
        // since no element in the list equals 4
        value = l.Single(i => i == 4);

        // Throws System.InvalidOperationException
        // since both 5 and 3 are greater than 1
        value = l.Single(i => i > 1);
        value = l.SingleOrDefault(i => i > 1);

    VB.NET: 

        ' Create a new generic list of ints
        Dim l As New List(Of Integer)

        l.Add(1) ' Add 1 to the list
        l.Add(5) ' Add 5 to the list
        l.Add(3) ' Add 3 to the list

        ' Returns 1 as only 1 satisfies the condition
        Dim value As Integer = l.Single(Function(i) i = 1)

        ' Returns the default value of int which is 0
        ' since no element in the list equals 4
        value = l.SingleOrDefault(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since no element in the list equals 4 
        value = l.Single(Function(i) i = 4)

        ' Throws System.InvalidOperationException
        ' since both 5 and 3 are greater than 1
        value = l.Single(Function(i) i > 1)
        value = l.SingleOrDefault(Function(i) i > 1)

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

    Posted May 10 2008, 02:27 PM by raj with 2 comment(s)
    Filed under: ,
  • AddItem Extension Method for BulletedList, CheckBoxList, DropDownList, ListBox, RadioButtonList

    We would have to write the below code to add a new item (with value) to any of these 5 controls (BulletedList, CheckBoxList, DropDownList, ListBox, RadioButtonList)

    C#:

        bulletedList.Items.Add(new ListItem("text", "value"));
        checkBoxList.Items.Add(new ListItem("text", "value"));
        dropDownList.Items.Add(new ListItem("text", "value"));
        listBox.Items.Add(new ListItem("text", "value"));
        radioButtonList.Items.Add(new ListItem("text", "value"));

    VB:

        bulletedList.Items.Add(New ListItem("text", "value"))
        checkBoxList.Items.Add(New ListItem("text", "value"))
        dropDownList.Items.Add(New ListItem("text", "value"))
        listBox.Items.Add(New ListItem("text", "value"))
        radioButtonList.Items.Add(New ListItem("text", "value"))

    I find it quite painful to write so much code just to add a new item (with value) to these controls and so I created a new AddItem extension method for the ListControl class (since all these 5 controls inherit from the ListControl class)

    C#:

        public static void AddItem(this ListControl lc, string text, string value)
        {
            lc.Items.Add(new ListItem(text, value));
        }

    VB:

        <Extension()> _
        Public Sub AddItem(ByVal lc As ListControl, ByVal text As String, ByVal value As String)
            lc.Items.Add(New ListItem(text, value))
        End Sub

    Now I can simply write the above code in a much simpler and cleaner way like below:

    C#:

        bulletedList.AddItem("text", "value");
        checkBoxList.AddItem("text", "value");
        dropDownList.AddItem("text", "value");
        listBox.AddItem("text", "value");
        radioButtonList.AddItem("text", "value");

    VB:

        bulletedList.AddItem("text", "value")
        checkBoxList.AddItem("text", "value")
        dropDownList.AddItem("text", "value")
        listBox.AddItem("text", "value")
        radioButtonList.AddItem("text", "value")

    Just 1 extension method which works for 5 controls to solve the problem :-) Cheers to object inheritance and cheers to Extension Methods ;-)

    Note: You can find a list of other cool and useful Extension Methods coded by me here

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~

  • Using Initial Capacity Constructor of StringBuilder for Extreme Performace

    You must have come across plenty of articles on the internet which talk about using the StringBuilder class when computing large strings for performance gains. Nothing wrong with that. However I have not seen many coders using the Initial Capacity constructor of the StringBuilder class which can further improve performace.

    Lets take a real world example. Suppose we had to compute a csv (comma seperated values) file for a table named Users which had the following structure:

    • UserID int
    • FirstName nvarchar(20)
    • LastName nvarchar(20)

    Our csv file would look like (for 2 records):

    1,Paul,Graham
    2,Scott,Guthrie

    Most coders would write the below code to compute the csv file:

        // Populate Users DataTable
        DataTable dtUsers = SomeFunctionWhichReturnsUsersDataTable();

        // Declare new StringBuilder
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        // Loop through Users DataTable
        for (int j = 0; j < dtUsers.Rows.Count; j++)
        {
            sb.Append(dtUsers.Rows[j]["UserID"].ToString()); // Append UserID
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["FirstName"].ToString()); // Append FirstName
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["LastName"].ToString()); // Append LastName
            sb.AppendLine(); // Append new line
        }

        return sb.ToString(); // Return StringBuilder contents

    Now lets write the above code more intelligently by using the Initial Capacity constructor of the StringBuilder class. We can actually guess the approximate length of the csv file before hand by considering below points:

    • Max length of UserID can be 10 characters, since max value of UserID can be 2147483647, since its datatype is int
    • Max length of FirstName can be 20 characters, since its datatype is nvarchar(20)
    • Max length of LastName can be 20 characters, since its datatype is nvarchar(20)
    • Also each csv file record has 2 comma characters which act as seperators, and 1 new line character

    Therefore the max length per record can be 54 characters (10[UserID] + 20[FirstName] + 20[LastName] + 2[2 comma characters] + 2[1 new line character]). So now we are absolutely sure that our csv file would have a max length of (54 * Number of Records) characters.

    If you are hell bent on having just one and only one memory allocation for the StringBuilder class, go ahead and set the Initial Capacity of the StringBuilder class to (54 * Number of Rows). However doing this would more often than not result in a lot of memory wastage as not all records would have their UserID set to 10 digit integers or their FirstName and LastName set to 20 character long strings. Therefore I usually follow the divide by 2 rule where I divide the max length per record value by 2. This way I am sure there wont ever be more than 2 memory (re)allocations and more often than not just a single memory allocation would do the job. Below is the intelligent version of above code:

        // Populate Users DataTable
        DataTable dtUsers = SomeFunctionWhichReturnsUsersDataTable();

        // Set a value of 54 to maxLengthPerRecord
        int maxLengthPerRecord = 54;

        // Apply divide by 2 rule
        maxLengthPerRecord = maxLengthPerRecord / 2;

        // Compute initialCapacity value
        int initialCapacity = dtUsers.Rows.Count * maxLengthPerRecord;
       
        // Declare new StringBuilder using the Initial Capacity constructor
        System.Text.StringBuilder sb = new System.Text.StringBuilder(initialCapacity);

        // Loop through Users DataTable
        for (int j = 0; j < dtUsers.Rows.Count; j++)
        {
            sb.Append(dtUsers.Rows[j]["UserID"].ToString()); // Append UserID
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["FirstName"].ToString()); // Append FirstName
            sb.Append(","); // Append comma
            sb.Append(dtUsers.Rows[j]["LastName"].ToString()); // Append LastName
            sb.AppendLine(); // Append new line
        }
       
        return sb.ToString(); // Return StringBuilder contents
     

    You might be thinking this is too much of an effort to save on a few memory reallocations. But the geek in me tries to visualize the performance gains and number of memory reallocations (read garbage collection cycles which are so expensive) which can be saved if we had to do the same task for a table with many columns and tens of thousands of records :-)

    Note: You can also consider dividing the max length per record by 3 or even 4, it all depends on your data structures and data patterns. Also the above code example uses a DataTable. However you can apply the same logic on a generic list or a DataReader as well.

    Cheers,
    Raj

    ~~~ CODING FOR ETERNITY !!! ~~~



StopGlobalWarming.org  
Powered by Community Server (Non-Commercial Edition), by Telligent Systems