Monday, October 22, 2007

T-SQL Recursion

I was working on task where I had a Parent/Child structure table in the database. I had a scenario where I needed to update all the parents of a child when this child’s value is updated. I thought of more than a way to do this and one of them was using cursors though knowing that it has some performance issues. Then I was advised by a colleague to do some investigations in T-SQL recursion. Here is the result of the investigation. Hope it will be useful.


Recursion is a well known technique in computer science. It can also be applied using T-SQL in SQL Server but there is a restriction which is that the nesting calls/levels is limited to the depth of 32 only. Even though, recursive SQL is a very useful technique. You can even implement a factorial recursive algorithm using it as I reference below. First let’s illustrate simple example of a parent/child table and then apply the recursion on it.

Egypt Population Sample

Let’s assume we have a structure representing the population in Egypt as the root and all its cities & districts in the following form:



Let’s represent this structure in a parent/child table (EgyptPopulation Table):



Now the case is that we want to update all roots of a certain leaf after the leaf value is changed as the following:

- We set the population of Mohandessin to 6 (instead of 4)

- Since mohandessin is a child of Cairo & Cairo is a child of Egypt(the root) then both will be affected
- Cario = Heliopolis + Maadi + Mohandessin = 5 + 3 + 6 = 14
- Egypt = Cairo + Alex = 14 + 7 = 21

Recursion will be a very useful technique to apply this. T-SQL recursion is similar to the regular recursion we use in programming. As we declare a method and call it in its own body putting in consideration a stopping condition in order not to enter an infinite loop, we will do the same in T-SQL recursion using stored procedures. Here is the implementation of the recursive stored procedure:

--This is only to drop the procedure if it was created before
IF EXISTS (SELECT * FROM sysobjects
WHERE id = object_id('UpdateEgyptPopulation')
and OBJECTPROPERTY(id, 'IsProcedure') = 1)
DROP PROCEDURE UpdateEgyptPopulation
GO

CREATE PROCEDURE UpdateEgyptPopulation
@childID INT --The ID of the updated child which value was changed (ex: Mohandessin)
AS
SET NOCOUNT ON
DECLARE
@parentID INT --A variable to hold the ID of the parent of the current child in the loop
BEGIN
SELECT
@parentID = ParentID FROM EgyptPopulation WHERE ID=@childID
IF (@parentID != -1) --Condition to test whether the root is reached or not
BEGIN
--Update the parent of the current child in the loop
UPDATE EgyptPopulation SET Goal = (SELECT SUM(Goal) FROM
EgyptPopulation WHERE ParentID = @parentID)
WHERE ID = @parentID
--Recurse to update all the parents to the root level passing the current parent ID
EXEC UpdateEgyptPopulation @parentID
END
ELSE
BEGIN
RETURN
--If the root node is reached (no more parents) end the recursion
END
END
GO

The logic in this sotred procedure is as follows:
- Passing the ID of the updated child in to the stored procedure
- Declaring a variable @parentID and querying the ID of the parent using the child’s ID
- If the ID of the parent is null (-1) then we stop the recursion
- If not, then we update the parent population by getting the sum of all its childs
- Then we call the same procedure by passing the ID of the parent itself to update it parent & so on until we reach the root (Egypt) which has no parents. In this condition the loop will be broken


Bare in mind that the number of nesting calls in limited to 32 only. This means that this technique cannot be applied on a parent/child structure with depth more than 32.


References
Recursion in T–SQL
http://msdn2.microsoft.com/en-us/library/Aa175801(SQL.80).aspx

Using recursion in stored procedures (Factorial example)
http://articles.techrepublic.com.com/5100-9592_11-5700193.html

Thursday, October 11, 2007

15+ Free Visual Studio Add-Ins

A list of 15+ FREE Add-ins for Visual Studio 2005. Some of these add-ins will help improve the quality of your code, while others will help you code faster.

http://www.carlj.ca/2007/09/25/15-free-visual-studio-add-ins/

11 Visual Studio 2005 IDE Tips and Tricks to Make You a More Productive Developer

Here are 11 tips and tricks for getting things done faster with the Visual Studio 2005 IDE (without using third-party add-ins or upgrading hardware). Yes, some of these tips and tricks may fall into the “obvious” category, but I think they are worth repeating. Many .NET developers are not taking advantage of even the basic time-saving techniques.

http://www.chinhdo.com/chinh/blog/category/programming/dotnet/

Public Hotfix Patch Available for VS 2005 F5 Debugging Performance Issue with ASP.NET

A significant delay may occur when you try to debug (using F5 to run/debug ASP.NET 2.0 applications using Visual Studio 2005.) an ASP.NET-connected application in Visual Studio 2005 this fix

http://weblogs.asp.net/scottgu/archive/2007/08/21/public-hotfix-patch-available-for-vs-2005-f5-debugging-performance-issue-with-asp-net.aspx

Wednesday, August 15, 2007

Telerik RAD TreeView Multiple Checboxes Selection with Load-On-Demand

I was working on a task where I was using Telerik RAD
TreeView Control in an ASP.Net Ajax Enabled Web page. I faced a small problem and found a solution for it which I think might be helpful and saves some time if you face the same problem

Here is the scenario of the problem:

- I was working with Ajax CallBacks and not Postbacks
- I wanted to enable multiple checkboxes selection on the RAD TreeView
- The treeview load with the load-on-demand concept. Which means the
first node is loaded and rendered an OnExpand, the child nodes are loaded from
DB using the expanded node ID. The initial state starts with only one node.
- After checking some nodes and hitting the OK button, the tvLocations1.CheckedNodes.Count property returned Zero at the server.
- I tried setting the AutoPostBackOnCheck property to true, the Tree posts back setting itself to its initial state (with only one node)

To ovecome being unable to read the checked nodes in the
server, I thought of this solution:
- Adding 3 hidden fields in the page to hold the checked nodes texts,
levels and values

<asp:HiddenField ID="hfSelectedNodeText" runat="server" />
<asp:HiddenField ID="hfSelectedNodeLevel" runat="server" />
<asp:HiddenField ID="hfSelectedNodeValue" runat="server" />


- Adding a script function to AfterClientCheck event that uses string concatenation to add the checks and unchecked nodes to the hidden fields
AfterClientCheck="AfterCheck"

function AfterCheck1(node)
{
if (node.Checked)
{
document.getElementById("<%= hfSelectedNodeText.ClientID%>").value += node.Text + '$';
document.getElementById("<%= hfSelectedNodeLevel.ClientID%>").value += node.Level + '$';
document.getElementById("<%= hfSelectedNodeValue.ClientID%>").value += node.Value + '$';
}
else
{
document.getElementById("<%= hfSelectedNodeText.ClientID%>").value = document.getElementById("<%= hfSelectedNodeText.ClientID%>").value.replace(node.Text+'$', "");
document.getElementById("<%= hfSelectedNodeLevel.ClientID%>").value = document.getElementById("<%= hfSelectedNodeLevel.ClientID%>").value.replace(node.Level+'$', "");
document.getElementById("&lt;%= hfSelectedNodeValue.ClientID%>").value = document.getElementById("<%= hfSelectedNodeValue.ClientID%>").value.replace(node.Value+'$', "");
}
}

- Reading the hidden fields from code behind in the Ok button OnClick event and splitting the value of the fields into string array:

string[] nodesText = SplitString(hfSelectedNodeText.Value);
string[] nodesLevel = SplitString(hfSelectedNodeLevel.Value);
string[] nodesValue = SplitString(hfSelectedNodeValue.Value);

Split Method (Server-Side):

private string[] SplitString(string sText)
{
string[] splittedArray = sText.Split(char.Parse('$'));
return splittedArray;
}

- Note that each array contains an empty element at the end as the last character is $
and the split string after it is empty string. This issue can be overcome by
looping on the array.Length – 1 like this:

for
(int i = 0; i < nodesText.Length - 1; i++)
{
//your code here
}

Hope this was useful...

Thursday, February 15, 2007

Installing Arabic Language Packs With MOSS 2007

Index

Purpose
Description
Steps of Installation
Tips
Useful References


Purpose

This article describes the way of installing Arabic language packs on MOSS 2007.

Description

Arabic language pack enables site owners and site collection administrators to create SharePoint sites and site collections in Arabic without requiring separate installation of the Arabic version of Microsoft Office SharePoint Server 2007. You install Arabic language pack, which contain Arabic site templates, on your front-end Web servers. When an administrator creates a site or a site collection based on Arabic site template, the text that appears on the site or the site collection is displayed in Arabic language and the direction of the portal will be RTL.

Note:
Some user interface elements such as error messages, notifications, and dialog boxes do not display in the Arabic language. This is because Office SharePoint Server 2007 relies on several supporting technologies - for example, the Microsoft .NET Framework, Microsoft Windows Workflow Foundation, Microsoft ASP.NET, and Microsoft SQL Server 2005 - some of which are localized into only a limited number of languages. If a user interface element is generated by any of the supporting technologies that is not localized into the language that the site administrator specified for the site, the user interface element appears in English.

Steps of Installation

Prerequisites

Before you install language packs on your front-end Web servers, you must do the following:
1- Install the Arabic language files on your front-end Web servers:
. Click Start > Control Panel > Regional and Language Options
. Select the Language tab
. Check on Install files for complex script and right-to-left languages then press the Apply button (*You will need to insert Windows product disc or provide the location of your Windows Server 2003 installation files.)
. When prompted to restart your computer, click Yes.
2- Install Office SharePoint Server 2007 on each of your front-end Web servers.
3- Run the SharePoint Products and Technologies Configuration Wizard on each of your front-end Web servers.

Installing Arabic language packs on your front-end Web servers

1. Run setup.exe
2. On the Installation Types page, click Basic.
3. The setup wizard runs and installs the Arabic language pack.
4. Rerun the SharePoint Products and Technologies Configuration Wizard, using the default settings. If you do not run the SharePoint Products and Technologies Configuration Wizard after you install a language pack, the language pack will not be installed properly. (*Very Important)

Rerun the SharePoint Products and Technologies Configuration Wizard

1. Click Start, point to All Programs, point to Administrative Tools, and then click SharePoint Products and Technologies Configuration Wizard.
2. On the Welcome to SharePoint Products and Technologies page, click Next.
3.Click Yes in the dialog box that alerts you that some services might need to be restarted during configuration.
4. On the Modify server farm settings page, click Do not disconnect from this server farm, and then click Next.
5. If the Modify SharePoint Central Administration Web Administration Settings page appears, do not modify any of the default settings, and then click Next.
6. On the Completing the SharePoint Products and Technologies Configuration Wizard page, click Next.
7. On the Configuration Successful page, click Finish.

Uninstalling language packs

If you no longer need to support Arabic language, you can remove the Arabic language pack by using Add/Remove Programs in Control Panel. Removing a language pack removes the language-specific site templates from your computer. All sites that were created with those language-specific site templates will no longer work (the URL will produce a HTTP 500 - Internal server error page). Reinstalling the language pack will make the site functional.

Tips

. Available and Unavailable templates for Arabic language pack

Note that when creating a New SharePoint Site using the Arabic language, unfortunately not all templates are available.

Available templates when using Arabic language:
. Collaboration (تعاون) category with all its templates
. Meetings (اجتماعات) category with all its templates


Available templates when using Arabic language

Unavailable templates when using Arabic language:
. Enterprise (مؤسسة) category with all its templates
. Publishing (نشر) category with all its templates

. Stemming feature is off by default for Arabic language pack

Stemming is a feature of the word breaker component used only by the query engine to determine where the word boundaries are in the stream of characters in the query. A stemmer extracts the root form of a given word. For example, ‘running’, ’ran,’ and ‘runner’ are all variants of the verb ‘to run’. In some languages, a stemmer expands the root form of a word to alternate forms. In Arabic language pack, Stemming is turned off by default.

Useful References

Deploy Language Packs:
http://technet2.microsoft.com/Office/en-us/library/26c07867-0150-463d-b21a-a6d42aecf05a1033.mspx?mfr=true (Microsoft Technical Library)

Plan for multilingual sites:
http://technet2.microsoft.com/Office/en-us/library/22d5dc9c-66bd-40d7-8c60-2a2a066db2241033.mspx?mfr=true (Microsoft Technical Library)

Changing the language of a site template (.stp) file:
http://msd2d.com/newsletter_tip.aspx?section=sharepoint&id=b8c591e0-a755-48d7-830d-ae8761c10676

List of LCID for languages:
http://www.microsoft.com/globaldev/reference/lcid-all.mspx