Thursday, October 26, 2006

Why use Stored Procedures over direct SQL calls?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/why_use_stored_procedures_over_direct_sql_calls.htm]

Two main ways to interact with the database: using a stored procedure vs. using a direct SQL statement. Here's a brainstorm of the pros and cons to each:

Technique (called from managed code): Pro Con
Stored Procedure
  • Performance, as SP is already on the database
  • Reusability - multiple sources (including other SP) can call a SP.
  • Security, especially against SQL injection attacks.
  • Maintainability - you can create the SP (and run and test it) in a database editor.
  • Powerful - A SP consists of multiple SQL statements.
  • Deployment - Modifying a database object is often easier than redeploying managed code.
  • Code Generation - You can code generate a data access layer off of stored procs (although most of the time it's code-generated off of table schemas).
  • Have to install each SP on the database
Sql Statement
  • Quicker to get started, especially for simple code and a RAD, non-production app.
  • Sql string is stored in managed code, so no need to install on the database.
  • Flexible - you're generating any SQL statement you want.
  • Lacks most of the benefits of a SP.

In general (of what I've seen), many enterprise apps will use Stored Procs, while sometimes a RAD will use raw SQL statements.

What has your experience been?

Wednesday, October 25, 2006

Getting data snapshots with the MassDataHandler

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/getting_data_snapshots_with_the_massdatahandler.htm]

The other day I had a to investigate some data corruption. A certain table started out with one set of data, I ran an upgrade process, and QA told me it wasn't upgrading correctly. The problem was that I needed to compare two snapshots of SQL data, from the same table. I know there are many ways to solve this problem. The way I solved it was with the open-source MassDataHandler.

One of the main purposes of this free tool is to convert data back and forth between an Xml format and stored SQL data in a database. So, with the "Use Existing Data" feature, I took a snapshot of the table (using a select clause to specify the columns and order) and saved it as an Xml file. I then ran some black-box upgrade process, and took a second snapshot of the table. Because I now had two xml files, I could easily just diff them (I prefer using Beyond Compare for this).

The idea was to reduce the problem from an unknown state (how to compare Sql data) to a known one (how to compare two Xml files).

Tuesday, October 24, 2006

The MassDataHandler 1.2 has been released!

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_massdatahandler_12_has_been_released.htm]

This is a free, open-source tool to assist with database unit testing. The new version offers several new features:

  • The GUI now offers the ability to ignore primary keys when generating from existing data.
  • The Build process has a reusable script to drop all foreign keys from a database. This makes it easier for you to adapt the demo script to your own project.
  • The Readme has been updated with better documentation.
  • A few miscellaneous bugs have been fixed.

You can download it here.

Monday, October 23, 2006

Comments as version control

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/comments_as_version_control.htm]

At every company I've been, I see source code with old code commented out instead of deleted. In a sense, this is almost using commenting like a primitive form of version control. I see pros & cons to this approach:

Pro:

  • In environments where requirements constantly change, some developers are more comfortable seeing how the chuck was previously written so that they can easily revert.
  • You may be intending to switch back to the previous code, and it's easier to see it if the code is commented out, as opposed to digging through version control.

Con:

  • As Steve McConnell suggests in Code Complete, the purpose of comments is to show the intent of your code. Using comments as version control can be misguided.
  • It can imply a lack of confidence. If the code is really no longer used, why not just delete it and make your code leaner.
  • It can bloat the source code very quickly, requiring future developers to read through more.

I think ideally old and obsolete code should be removed instead of commented out (makes for leaner, easier-to-read code), but I can see the other approach in certain development cultures.

Sunday, October 22, 2006

How many ways to represent True and False

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/how_many_ways_to_represent_true_and_false.htm]

I was recently serializing data from both the database and user input, and it made me reflect on how many ways you can represent a boolean value as a literal string. For an English-language app (no globalization), here are several ways to represent a boolean:
  • TRUE / FALSE - converting from a literal string.
  • T / F - users who only want to enter the first character.
  • Yes / No - non-technical users who want "friendly" terms.
  • Y / N - again, users who want to only enter the first character.
  • 1/0 - A bit, such as how SQL Server stores booleans.

And of course, the first three options can be case insensitive and trimmed white space (i.e. "tRUe" becomes "TRUE").

I had talked about using Convert.ToString to convert different objects to string, so I'd initially look at it's related method: Convert.ToBoolean. But one quickly sees that that won't handle all the cases (and with good reason). The only literal string it takes from this group is "true"/"false". For example, it would handle converting the integer 1, but not the literal string "1". Having a single function that just converts these different inputs to a boolean is a nice convenience. Here's a sample:

public static bool ConvertToBoolean(string strVal)
{
  if (string.IsNullOrEmpty(strVal))
    return false;

  strVal = strVal.ToUpper().Trim();

  if (strVal == "TRUE" || strVal == "T" || strVal == "1"
    || strVal == "YES" || strVal == "Y")
    return true;
  else if (strVal == "FALSE" || strVal == "F" || strVal == "0"
    || strVal == "NO" || strVal == "N")
    return false;
  else
    throw new ArgumentException("Cannot convert '"
    + strVal + "' to Boolean.");
}

Wednesday, October 18, 2006

What to do before just asking someone?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/what_to_do_before_just_asking_someone.htm]

Some projects have the local superstar. Any whenever anyone has a question, rather than figure it out for themselves (or even try to), they just ask their local star. There are two problems to this approach: (1) It eventually burdens that "star", and (2) It weakens the average guy's ability to find out info for himself.

Sometimes you need the answer right away, so you'll just ask someone. (And it would take too long to figure out yourself). However, most of the time it's worth first taking a stab at it yourself. Here are some ideas:

  • Tell yourself that you're just going to try for the next 5 minutes (If you say "I don't have 5 minutes", consider does anyone else?)
  • Read the documentation (feature spec, help doc, inline code comments, etc...)
  • Google the buzzwords, especially if it's a unique error message (like '__pendingCallbacks[...].async' is null or not an object)
  • Step back and think of the higher level concepts (maybe there's a knowledge gap you need to fill)
  • Step through the code in the debugger (such as to see the context it's being used in)
  • Use SQL Profiler to find data sources (what SP does this call?
  • Start at the problem and try working backwards
  • Find the steps necessary to deterministically reproduce the problem, then take a divide and conquer approach, checking each part of the code in isolation to see if it is the cause.
  • Work on something else and come back to the problem later with a fresh mind.

While having other star coworkers is a nice safety net, it is a luxury that may not always be there. And during those times, it will be nice to have had the practice at figuring out answers for oneself. Besides, the more someone practices at solving problems, the more likely it is that they'll become that goto guy that everyone else asks questions too.

Tuesday, October 17, 2006

Sql Tools - Profiler and SqlCommand

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/sql_tools__profiler_and_sqlcommand.htm]

Everyone knows how to use SQL Management Studio, but there are two other useful tools that SQL Server 2005 has.

  • SQL Profiler - This lets you profile the SQL Server calls. It's very effective to determine what page is making which calls (and how long those calls take). It's much easier to just run profiler, as opposed to stepping through all the code to find what SP gets triggered when you click Button X.
  • SqlCmd - This is the command line for SQL Server (replaces osql for SQL 2000). It's useful when you need to Automate, or don't want the full SQL GUI installed (such as when you have limited space on a build server).