Monday, December 31, 2007

Bye Bye 2007

2007 was really a vibrant year for me. New Company, new projects, new peoples, new challenges, achievements, awards, anxiety and excitement were some few colors of 2007, but above all, becoming a father will make 2007 is the most memorable year of my life. I am very thankful to my family and friends who gave their support in every up and down phase of my life. I don't believe in resolutions but keeping the tradition, I want to make this resolution and I will my try my best to follow this resolution throughout the year – I will start my sketching again. I am an artist by instinct. I left sketching few years back when I went college for engineering. I know this can't be excuse but really that time I just wanted to concentrate on my career. This unusual blog post is note to me and it will keep reminding me of my New Year resolution.

Sunday, December 30, 2007

RedGate SQL Data Generator

RedGate launched a new tool for generating SQL server for dummy/test data.

Features:
- Full SQL Server 2000 and 2005 support
- All data types supported except CLR types
- Pre & Post Scripts execution
- Command-line access version
- Import data from CSV or SQL tables
- Customizable generator settings that allow configuring the amount of nulls, unique values, minimum and maximum values, etc..
- Diverse range of inbuilt generators

Please visit here for more detail.

By the way, I have already created few PERL scripts to achieve same type functionality to some extent.

Thursday, December 20, 2007

Yet another good article on Cluster and Non cluster index

Take the example of a phone book. The actual data - that is, the name, address and phone number records - is ordered by the name. If you want to look up Joe Bloggs's phone number, you open the book somewhere near the middle, maybe see the names there start with "M", but "Bloggs" is before "M", so you go a bit earlier in the book. You keep narrowing it down until you find the entry labelled Bloggs, and that's it - all the data for that record is right there. That's a bit like a clustered index.

On the other hand, a book might have a table of contents, sorted alphabetically. If you want to find out about llamas, you search the contents for llamas, which probably then gives you a page number, at which point you go to the page, and there's the data about llamas. The difference here is that you've had to do an extra bit of indirection - following the page number pointer - in order to get to the data. You can probably now see that while you can have as many tables of contents, ordered in any way you like, one set of data can only be physically arranged in one way. This means you can have many non-clustered indexes, but only one clustered index on a table.

Full Article

Wednesday, December 19, 2007

Perl 5.10 is out

Perl is no longer teenager. Its Perl's 20th Bithday and its coming in its brand new suite.
Checkout new features of 5.10 in this document.

Of course you have to wait for 5.10 and chances are you never get it but till then Perl 5 is rocking.

Tuesday, December 18, 2007

String - Reference or Value Type

In my interviews, I observed that 90% candidates don't have clear understanding of Reference or Value Types in .NET. I am not going to explain these two things here but want to clear one interesting point here.

Though String in .NET is Reference type object but it works as Value type.
Following code snippet will print "test"

static void Main(string[] args)

{

string str = "test";

ChangeString(str);

Console.WriteLine(str);

Console.ReadLine();

}

static void ChangeString(string str)

{

str += " Changed";

}





Following some line will better explain the things:
although strings are reference types, they work rather more like value types. When one string is set to the value of another, eg
string s1 = "hello";
string s2 = s1;

Then s2 does at this point reference the same string object as s1. However, when the value of s1 is changed, for instance with

s1 = "goodbye";

what happens is that a new string object is created for s1 to point to. Hence, following this piece of code, s1 equals "goodbye", whereas s2 still equals "hello".

The reason for this behaviour is that string objects are 'immutable'. That is, the properties of these objects can't themselves change. So in order to change what a string variable references, a new string object must be created.


Restrictions on TempDB

I found it on internet. Thought you guys like to know:

  • Adding filegroups.
  • Backing up or restoring the database.
  • Changing collation. The default collation is the server collation.
  • Changing the database owner. tempdb is owned by dbo.
  • Creating a database snapshot.
  • Dropping the database.
  • Dropping the guest user from the database.
  • Participating in database mirroring.
  • Removing the primary filegroup, primary data file, or log file.
  • Renaming the database or primary filegroup.
  • Running DBCC CHECKALLOC.
  • Running DBCC CHECKCATALOG.
  • Setting the database to OFFLINE.
  • Setting the database or primary filegroup to READ_ONLY.

Monday, December 17, 2007

SQL Helper - New functionalities (2)

In my last posts, I talked about SQL helper developed by me. Following are two new functionalities added recently to application:

  1. Create database documentation in word or html format
  2. Do Uppercase SQL keywords option in Stored procedures and functions.

Tuesday, November 27, 2007

Part 1: Using XML in SQL Server 2005

Suppose you want to generate following output from stored procedure :

1 <Companies>

2 <Company id="1" name="Company A">

3 <Address>

4 <Street>101 A St.Street>

5 <City>HaysCity>

6 <State>KansasState>

7 <Zip>67601Zip>

8 Address>

9 <Contacts>

10 <Contact id="1" name="Bob Black">

11 <ContactInfo email="bb@companyA.com" phone="(123) 456-7890" />

12 <Login uid="bb" pwd="bb7" />

13 Contact>

14 <Contact id="2" name="Bob Brown">

15 <ContactInfo email="bbn@companyA.com" phone="(123) 456-7891" />

16 <Login uid="bn" pwd="bn1" />

17 Contact>

18 <Contact id="3" name="Bob White">

19 <ContactInfo email="bw@companyA.com" phone="(123) 456-7892" />

20 <Login uid="bw" pwd="bw2" />

21 Contact>

22 Contacts>

23 Company>

24 Companies>



Following is the code snippet to achieve above output from SQL query

select

Company.Cmp_id "@id",

Company.[Name] "@name",

Company.Address "Address/Street",

Company.City "Address/City",

Company.State "Address/State",

Company.Zip "Address/Zip",

(

select

Contact.Cnt_id "@id",

Contact.[Name] "@name",

Contact.Email "ContactInfo/@email",

Contact.Phone "ContactInfo/@phone",

Contact.UserName "Login/@uid",

Contact.Password "Login/@pwd"

from

Contact

where

Contact.Cmp_id = @CompanyId

order by

Contact.[Name]

for xml path ('Contact'), root('Contacts'), type

)

from

Company

where

Company.Cmp_id = @CompanyId

for xml path ('Company'), root('Companies'), type

Monday, November 12, 2007

Showing enum as dropdown or listbox

Following function returns ListItemCollection for given enum type. This ListItemCollection can be bound to dropdown or listbox:

public static System.Web.UI.WebControls.ListItemCollection GetListItemsFromEnum(Type typeOfEnum)
{
System.Web.UI.WebControls.ListItemCollection lstColl
= new System.Web.UI.WebControls.ListItemCollection();
foreach (string name in Enum.GetNames(typeOfEnum))
{
System.Web.UI.WebControls.ListItem li
= new System.Web.UI.WebControls.ListItem();
li.Text = name;
li.Value = ((int)Enum.Parse(typeOfEnum, name)).ToString();
lstColl.Add(li);
}
return lstColl;
}

Friday, October 12, 2007

ASP.NET - Performing long running process asynchronously with out duplication

Sometimes in our web pages we need to perform some long running process. You must be agree that instead of watching wait cursor for long running process, user can do some other activity in same web application with out blocking. Those who do not know AJAX or want to do some quick fix in their ASP.NET code, following is the code which targets following objectives:
  1. User should not be blocked on web page, he can perform some other activity. That means after post back, process should be run in background and user instantly gets control after starting the process.
  2. Web server connection time out for long running process.
  3. Even instantly getting control after starting the process, user should be able to start the same process only after completion of previous process started by the same user. I used mutex for it.
Following is the code:
using System.Threading;

// Button click event
protected void btnLoad_Click(object sender, EventArgs e)
{
try
{
ThreadPool.QueueUserWorkItem(new WaitCallback(LoadLog));
}
catch (Exception ex)
{
lblMessage.Text = "Your job could not be submittited due to following error:
" + ex.Message;
lblMessage.CssClass = "Error";
}
lblMessage.Visible = true;
}

// In above code LoadLog is the function which starts long running process
// Following is the code for LoadLog
private void LoadLog(object state)
{

string mutexKey =Thread.CurrentPrincipal.Identity.Name;
mutexKey = mutexKey.Replace(@"\", "_"); // Required otherwise mutex will consider its a file system path
Mutex mMutex = new Mutex(false, mutexKey + "_LoadLogs");
mMutex.WaitOne();
try
{
//Here your long running process
Thread.Sleep(1000000); // Don't try this line, just for example.
}
finally
{
mMutex.ReleaseMutex();
}
}

Thursday, October 11, 2007

Sproc Vs UDF

I got this from SQL server magazine. Yeah.. I know this is very basic thing but honestly speaking, I did not know about point 3, so this is note for myself:
  1. A UDF must return a value-a single result set. A stored procedure can return a value-or even multiple result sets-but doesn't have to.
  2. You can use a UDF directly in a SELECT statement as well as in ORDER BY, WHERE, and FROM clauses, but you can't use a stored procedure in a SELECT statement.
  3. A UDF can't use a nondeterministic function such as GETDATE(), NEWID(), or RAND(), whereas a stored procedure can use such functions. A nondeterministic function is one that can return a different result given the same input parameters.
  4. A UDF can't change server environment variables; a stored procedure can.
  5. A UDF always stops execution of T-SQL code when an error occurs, whereas a stored procedure continues to the next instruction if you've used proper error handling code.
  6. A UDF can not execute DDL statements. It can perform insert, update and delete operations on only temporary tables not on permanent tables.
  7. You can't have trannsactions in UDF
  8. You can call stored procedures with in a stored procedure but not with in a function. Ofcourse you can call functions with in a function.

Friday, October 05, 2007

New version of SandCastle is available

The latest version of SandcastleGUI is available for download at http://www.inchl.nl. This release of SandcastleGUI targets the September CTP build of Microsoft's Sandcastle.

Microsoft did a great job fixing over 50 issues that were reported by customers, also they fixed over 500 work items to support the Orcas (Visual Studio 2008) RTM.

Microsoft's Sandcastle September 2007 CTP build does no longer contain the .NET framework reflection data. Because this data can be generated in runtime it didn't make sense to include over 500 MB of reflection data into an installation file.

Also for each version of the .NET framework and the chosen Sandcastle template this reflection data is different.

SandcastleGUI introduces a new feature that allows caching of this data because the generation of it is very time consuming.

Thursday, October 04, 2007

Implementing timer operation in window service

Following code snippet shows how can we perform a operation on timer event in window service:


public partial class MyService : ServiceBase
{
private System.Timers.Timer timer2;
private bool IsProcessRunning = false;

public MyService()
{
InitializeComponent();
this.ServiceName = "MyService";
timer2 = new System.Timers.Timer();
timer2.Enabled = false;
timer2.Interval = "10000";
timer2.Elapsed += new System.Timers.ElapsedEventHandler(timer2_Elapsed);
}

protected override void OnStart(string[] args)
{
timer2.Enabled = true;
timer2.Start();
}

protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}

void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (!IsProcessRunning)
{
try
{
IsProcessRunning = true;
// Add process here
InsertRecord();
}
catch (Exception ex)
{
this.EventLog.WriteEntry(ex.Message, EventLogEntryType.Error, 1000);
}
finally
{
IsProcessRunning = false;
}
}
}
}

Wednesday, October 03, 2007

Javascript debugging in Visual Studio

In order to debug javascript code in ASP.NET application you need to following thing:
  1. Enable script debugging option for Internet Explorer.
  2. Open inetmgr and right click on the web application project. Set true to option "Enable ASP client side debugging".
  3. There is a quick and dirty way - Add "debugger;" command as the first line of the javascript function which you want to debug.

Monday, October 01, 2007

Performing case sensitive comparison in SQL 2005

Using following query, you can perform case sensitive comparison for strings in SQL 2005 even if your database was configured for case insensitive comparison:

SELECT UserId, email
FROM aspnet_membership
WHERE email = 'test@test.com' COLLATE SQL_Latin1_General_CP1_CS_AS

Thursday, September 27, 2007

SQL Batch Insert

Following snippet can be used to quickly upload ‘|’ separated record in SQL 2005 database table:

bulk insert cass.dbo.Stage1Input

FROM 'E:\tmp\cass\InputRecordDB.txt'

WITH

(

BATCHSIZE = 5000,

FIELDTERMINATOR ='|'

)

GO

Tuesday, September 11, 2007

My son Aditya

My son Aditya aka Adi, who makes sure that I should not take more then two hours sleep at night.

Monday, September 10, 2007

SQL Helper 1.0


In my day to day SQL Server development tasks I wanted a tool which can help me automating deployment tasks. There are some great tools already available like SQL Management Console and Red-Gate SQL/Data Compare, however, these tools get failed when you have very specific requirements like:

  • Loading of object based on specific regular expression pattern – For instance, you specifically wants to load objects for scripting whose names qualifies a specific regular expression pattern
  • Loading of object from a file list – For instance, you have list of StoreProcedures in a flat file and you want to create a SQL Create script for these stored procedures only.
  • Both Drop and Create Schema at once – Management Console either let you create a drop schema or create schema. This tool provides option for both.
  • Comparing two databases – just like any other database compare tool do. Additionally I can control objects to be compared by regular expressions. Output file have list of different and common objects between two databases.

To address, these specific requirements I developed SQL Helper.



Please leave your email in comments to get a copy of source-code/exe of SQL Helper 1.0.

Friday, June 08, 2007

Free Ebooks

Absolutely free!!! For old book lovers this web site is treasure. Choose from variety of formats.

http://manybooks.net

Monday, May 21, 2007

.Net and Windows Security Part 1

This is three part series. Following is the breakdown of this series:

  1. First Part: General Windows Security Concepts
  2. Second Part: .Net classes for handling windows security
  3. Third Part: Sample code for adding/deleting user in windows shared folder security

Users and Groups

In Windows NT/2000/XP/2003 and now in VISTA every process runs in a security context. Every process is associated with a Windows Identity that is called a prinicipal. Whenever a process access a resource (file, directory, registry, event, mutex ..), principal is checked against resource's access rule. For now you can think resource's access rules as a table which identifies which user/group has which type of rights on the resource. In above line, I mentioned user/group because Windows presents notion of Group. Every user must belong to one or several groups.

Session Logon

A new Session Logon is created as soon as user logs in the system. Session contains security token. Whenever user launches a process (or process launch a new process), new process inherit security token and runs in security context of user or parent process. Windows automatically creates three session logon whenever it starts up: System Session, Local Session and Network Session.

Windows Security Identifier (SID)

Windows internally indentifies each user or group by its SID. It is a unique number and looks like a GUID, but actually this is not GUID. It has certain pattern which conforms to Security Descriptor Definition Language (SDDL). For example SID "S-1-5-21-790525478-1425521274-725345543-500" represent administrator account on my laptop. Usually SID which ends up with 500 belongs to built in administrator group. Windows has some default SIDs which are called Well-Known SIDs. Following list identifies some important Well-Known SIDs:

Anonymous Logon

(S-1-5-7)

A user who has connected to the computer without supplying a user name and password.

Authenticated Users

(S-1-5-11)

Includes all users and computers whose identities have been authenticated. Authenticated Users does not include Guest even if the Guest account has a password.

Everyone

(S-1-1-0)

On computers running Windows XP Professional, Everyone includes Authenticated Users and Guest. On computers running earlier versions of the operating system, Everyone includes Authenticated Users and Guest plus Anonymous Logon.

Terminal Server Users

(S-1-5-13)


Includes all users who have logged on to a Terminal Services server that is in Terminal Services version 4.0 application compatibility mode.


Windows Security Descriptor

Window Security Descriptor is the core of window security (at least from the developer point of view) and every resource must have security descriptor as soon as it is created. On msdn, you can find several documents explaining Win32 Security Descriptor in details. Following is the breakdown of SD structure:

  • Owner SID
  • Group (optional, adopted from posix security structure)
  • Control Flags
  • DACL (Discretionary access control list)
  • SACL (System access control list)

DACL

DACL is the ordered list/array of Access Control Elements (ACE). ACE is basically the rights or permissions assigned to user or group. There are two type of ACE: Allow and Deny. It can be understand by a very basic example. Suppose a user has only read-allow permission on a directory. This "only read-allow" permission cannot stop him from creating a new file/directory or even from deleting the directory. For proper read only permissions, user must be given "write-deny" permission also. It is important to note that ACEs are evaluated in the order that they are stored in the DACL. Windows does not necessarily evaluate all ACEs during an access right request.

SACL

SACL is another list of ACE. In normal scenarios, developer may not need to handle this list. ACEs in SACL are used for audit permissions. For example: rights grant event should be logged or not.


Friday, May 18, 2007

Office 2007 - I’m Love’n it

Well, besides irresistible sleek user interface, Office 2007 is in true sense a developer's package. I have following point to support my statement:

  1. Following OpenXml standards as well as supports MS proprietary format. So being a XML expert, I can play with package in my way.
  2. Developer Band: Now Word and excel are not toys for only managers. Right!!
  3. Word: Excellent support for blogging. I can write a complete blog in word and publish it to my blogging site even without going on that (I wrote this blog offline, when I was just going to sleep)
  4. Outlook: Excellent RSS Feed functionality, you can even have full post as an attachment.

Happy Blogging.

Friday, May 11, 2007

Deep Serialization using MemoryStream

I found this quite easy to use MemoryStream and BinaryFormatter object to provide deep copy functionality.

For full article, please visit : http://www.c-sharpcorner.com/UploadFile/sd_surajit/cloning05032007012620AM/cloning.aspx

Following is the code snippet for quick look:

using System.IO;

using System.Runtime.Serialization.Formatters.Binary;



public
Class Test : IClonable

{

public Test()

{

}

// deep copy in separeate memory space

public
object Clone()

{

MemoryStream ms = new MemoryStream();

BinaryFormatter bf = new BinaryFormatter();

bf.Serialize(ms, this);

ms.Position = 0;

object obj = bf.Deserialize(ms);

ms.Close();

return obj;

}

}

Tuesday, May 08, 2007

A Custom Generic Collection which has List as well as Dictionary functionality for Custom Entity Classes

I frequently need a collection which List as well as Dictionary functionality for custom entity classes. So I wrote following generic class which provides the same functionality. There is one prerequisite for this class: Custom entity class should have override function ToString() which actually returns a unique key for this collection. Following is the code for Custom class:

using System;

using System.Collections.Generic;

public
class
CC<T> : IEnumerable<T>

{


public
List<T> List = new
List<T>();


public
Dictionary<string, T> Dict = new
Dictionary<string, T>();


public
void Add(T obj)

{

List.Add(obj);

Dict.Add(obj.ToString(), obj);

}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

{


return PRIVGetEnumerator();

}


IEnumerator<T> IEnumerable<T>.GetEnumerator()

{


return PRIVGetEnumerator();

}



private
IEnumerator<T> PRIVGetEnumerator()

{


foreach (T obj in List)


yield
return obj;

}



public
bool Contains(String key)

{


return (Dict.ContainsKey(key));

}



public
void Remove(String key)

{

Dict.Remove(key);


for (int i = 0; i < List.Count; i++)

{


if (List[i].ToString().Equals(key))

{

List.RemoveAt(i);


break;

}

}

}



public
void RemoveAt(int index)

{

Dict.Remove(List[index].ToString());

List.RemoveAt(index);

}



public T this[int index]

{


get

{


return
this.List[index];

}


set

{

List[index] = value;


if (!Dict.ContainsKey(value.ToString()))

Dict.Add(value.ToString(), value);

}

}



public T this[string key]

{


get

{


return Dict[key];

}


set

{


if (!Dict.ContainsKey(key))

{

Dict[key] = value;

List.Add(value);

}


}

}



public
void CopyTo(T[] array, int index)

{

List.CopyTo(array, index);

}



public
void AddRange(List<T> value)

{


for (int i = 0; (i < value.Count); i = (i + 1))

{


this.Add(value[i]);

}

}



public
Dictionary<string, T>.KeyCollection Keys

{


get

{


return (Dict.Keys);

}

}



public
Dictionary<string, T>.ValueCollection Values

{


get

{


return (Dict.Values);

}

}



}


Following is the example of custom entity class:

using System;

using System.Xml.Serialization;

public
class
Person

{


private
string _id = "";


///
<summary>


/// Set or Get _id


///
</summary>

[XmlElement(ElementName = "Id")]


public
string Id

{


set { this._id = value; }


get { return
this._id; }

}



private
string _FirstName = "";


///
<summary>


/// Set or Get _FirstName


///
</summary>

[XmlElement(ElementName = "FirstName")]


public
string FirstName

{


set { this._FirstName = value; }


get { return
this._FirstName; }

}



private
string _LastName = "";


///
<summary>


/// Set or Get _LastName


///
</summary>

[XmlElement(ElementName = "LastName")]


public
string LastName

{


set { this._LastName = value; }


get { return
this._LastName; }

}



public
override
string ToString()

{


return
this.Id;

}


public Person(string id, string fName, string lName)

{


this.Id = id;


this.FirstName = fName;


this.LastName = lName;

}


}

Finally, following is the code snippet which shows how we can use this custom generic class:

class
Program

{


static
void Main(string[] args)

{



CC<Person> myCC = new
CC<Person>();

myCC.Add(new
Person("1", "Tom", "Hanks"));

myCC.Add(new
Person("2", "Julia", "Roberts"));

myCC.Add(new
Person("3", "Johny", "Depp"));


myCC[1] = new
Person("2", "Orlando", "Bloom");

myCC["4"] = new
Person("4", "Leonardo", "Dacaprio");

myCC.RemoveAt(0);



foreach (Person p in myCC)


Console.WriteLine(p.FirstName);


Console.ReadLine();

}

}


Happy Movies!!!


Tuesday, April 24, 2007

Test Post from Word 2007

This is test blog using Word 2007

Wednesday, March 28, 2007

Getting correct object type

Following code snippet demonstrates how can we use GetType function to get correct object type in inheritance hierarchy

public interface A
{
void print();

}

public class B : A
{
void A.print()
{
Console.WriteLine("B");
}
}

public class C : A
{
void A.print()
{
Console.WriteLine("C");
}
}


public class MyClass
{
public static void Main()
{
A a = new C();
Console.WriteLine("#: " + a.GetType().Name);
a.print();
RL();
}

}

Tuesday, March 27, 2007

SMTP Managed Event Sink for scanning incoming emails

I want to scan all incoming mails using Managed Event sink. I am implementing IMailTransportSubmission Interface.

void IMailTransportSubmission.OnMessageSubmission(
MailMsg message,
IMailTransportNotify notify,
IntPtr context)
{
try
{
// Fill details of the Message in database
FillData(message);
}
catch (Exception ex)
{
EventLog.WriteEntry(
Assembly.GetExecutingAssembly().FullName,
ex.Message + "\n" + ex.StackTrace.ToString(),
EventLogEntryType.Error);
}
finally
{
if (null != message)
Marshal.ReleaseComObject(message);

}
}


I am using following command to bind the event sink:

cscript smtpreg.vbs /add 1 OnTransportSubmission "MyEventSink.ManagedSink" MyEventSink.ManagedSink.Sink "MAIL FROM=*" 28001

I have a development exchange server. When I put a message in “pickup” directory, a entry for this message is inserted into database. That means my event sink working fine, but I am not sure how to test it for incoming message as this development exchange doesn’t have dns entries and I have to check event sink functionality for incoming mail from same development server somehow. First thing I want to know that whether I have implemented correct interface for scanning incoming mails. Two, whether I have registered correct event for incoming mails.

Tuesday, March 06, 2007

SharePoint Versioning Algorithm

In my current project I need to implement versioning of the document stored in the SQL Server in the same way as SharePoint. I wrote following C# code to simulate versioning of SharePoint:

    int majorVersion = 0;
int maxMajorVersion = 2;
int maxMinorVersion = 20; // default 511;
string version = string.Empty;
int counter = 1;
int id = 1;

int maxId = 512 * maxMajorVersion;

List<int> lstNxtVersionIds = new List<int>();
for (int i = 1; i <= maxMajorVersion; i++)
lstNxtVersionIds.Add(i*512);

for (int i = 1; i<=maxId & id<=maxId; i++)
{
if (counter == maxMinorVersion)
{
version = majorVersion.ToString() + "." + counter.ToString();
Console.WriteLine ("id {0}, version {1}", id, version);
if (majorVersion < maxMajorVersion)
{
majorVersion++;

foreach (int nxtVersionId in lstNxtVersionIds)
{
if (id < nxtVersionId)
{
id = nxtVersionId;
break;
}
}
}
else if (majorVersion == maxMajorVersion)
break;
counter = 0;
}
version = majorVersion.ToString() + "." + counter.ToString();
Console.WriteLine ("id {0}, version {1}", id, version);

id++;
counter++;

Thursday, February 22, 2007

XML and SQL Server 2005

Here are two interesting articles on usage of XML in SQL 2005:

Some Usages for XML

I've Got the XML - Now What?

Wednesday, January 31, 2007

Friday, January 19, 2007

C# Passing Comma Seperated Stored Procedure Paramter

I came across passing a very long comma seperated string as a Stored Procedure Parameter. There is character limit on SqlParameter, that is one. The second thing I didn't want to pass individual string as parameters and calling same Stored Procedure for each string. That would have been clear and present performance hit. So I wrote following piece of code to avoid this situation. Break large string into small strings that can be accepted by SqlParameter.

string tmpMatterSpaceNames = string.Empty;
int lowerLimit = Constants.SqlParamCharLimit - 200;
StringCollection objStrCollection = new StringCollection();
foreach (string matterSpaceName in objNV.AllKeys)
{
tmpMatterSpaceNames += "'" + matterSpaceName + "',";
if (tmpMatterSpaceNames.Length > lowerLimit)
{
tmpMatterSpaceNames = Regex.Replace(tmpMatterSpaceNames, @",$", "");
objStrCollection.Add(tmpMatterSpaceNames);
tmpMatterSpaceNames = string.Empty;
}
}
if (tmpMatterSpaceNames != string.Empty)
{
tmpMatterSpaceNames = Regex.Replace(tmpMatterSpaceNames, @",$", "");
objStrCollection.Add(tmpMatterSpaceNames);
}

foreach (string matterSpaceNames in objStrCollection)
objMSDao.UpdateSourceCreatedFlag (matterSpaceNames, true);

Saturday, January 13, 2007

A Day in the Life of Indian Village

In Pragati Maidan Delhi, I find this place pretty interesting. This place presents models of indian villages across the different cultures. You can also see old household, crockeries and bull carts here. Posted by Picasa