Tuesday, January 31, 2012

ASP.NET MVC 3 Walkthroughs & Books

ASP.NET MVC 3 Walkthroughs & Books

1.    Intro to ASP.NET MVC 3 - Rick Anderson

http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part1-cs

2.    Building an MVC 3 App with Database First – Julie Lerman

a.     http://msdn.microsoft.com/en-us/data/gg685489

3.    Walkthrough: Retrieving Entity Types with a Stored Procedure (Entity Data Model Tools

a.     http://msdn.microsoft.com/en-us/library/cc716672.aspx

4.    Book – Wrox - Professional ASP.NET MVC 3

http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-3.productCd-1118076583,descCd-DOWNLOAD.html

Last n Months Display-Value Pair for DropDown List greater than a minimumm date

Create PROCEDURE [dbo].[ts_Dates]

@isTo bit

AS

 

/*

-----------------------------------------------------

--Last Dates Display-Value Pair for DropDown List

for date greater than

-----------------------------------------------------

exec [dbo].[ts_Dates] 0

exec [dbo].[ts_Dates] 1

*/

 

declare @minToDate datetime

declare @minFromDate datetime

select @minToDate = min(<date>) from <table>;

select @minFromDate = DATEADD(MONTH,-1,min(<date>)) from <table>;

--print @minToDate

--print @minFromDate

 

 

if @isTo = 1

       begin

              --Display                                   Value

              ------------------------------------------- --------------

              --February 29, 2012                         2/29/2012

              --January 31, 2012                          1/31/2012

              --December 31, 2011                         12/31/2011

 

        --with

              WITH R(N) AS (

              sELECT 0

              UNION ALL

              SELECT N+1  FROM R

              WHERE N < 100 )

              , cte2 (Display, Value, [date]) as (

              SELECT DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE()))

              + ' ' + CONVERT(VARCHAR(4),DATEPART(Day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,-N,GETDATE()))+1,0))))

              + ', ' + CAST(DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE())) AS VARCHAR(4)) AS Display

              , CONVERT(VARCHAR(4),DATEPART(MONTH,DATEADD(MONTH,-N,GETDATE())))

               + '/'

               + CONVERT(VARCHAR(4),DATEPART(Day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,-N,GETDATE()))+1,0))))

               +'/' + CONVERT(VARCHAR(4),DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE()))) AS [Value]

              , DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,-N,GETDATE()))+1,0)) as [date]

              FROM R )

              select * from cte2 where [date] > @minToDate

       end

else

       begin

              --Display                                Value

              ---------------------------------------- -----------

              --February 1, 2012                       2/1/2012

              --January 1, 2012                        1/1/2012

              --December 1, 2011                       12/1/2011

              WITH R(N) AS (

              sELECT 0

              UNION ALL

              SELECT N+1  FROM R

              WHERE N < 100 )

              , cte2 (Display, Value, [date]) as (

              SELECT DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE())) + ' 1, ' +

                CAST(DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE())) AS VARCHAR(4)) AS Display

              , CONVERT(VARCHAR(4),DATEPART(MONTH,DATEADD(MONTH,-N,GETDATE())))

               + '/1/' + CONVERT(VARCHAR(4),DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE()))) AS [Value]

               , DATEADD(MONTH, DATEDIFF(MONTH, 0, DATEADD(MONTH,-N,GETDATE())), 0) as [date]

              FROM R )

              select * from cte2 where [date] > @minFromDate

  end

Create

PROCEDURE [dbo].[ts_Dates]

@isTo bit

AS

 

/*

-----------------------------------------------------

--Last 100 Months Display-Value Pair for DropDown List

-----------------------------------------------------

exec [dbo].[ts_Dates] 0

exec [dbo].[ts_Dates] 1

*/

 

if @isTo = 1

       begin

              --Display                                   Value

              ------------------------------------------- --------------

              --February 29, 2012                         2/29/2012

              --January 31, 2012                          1/31/2012

              --December 31, 2011                         12/31/2011

 

              WITH R(N) AS (

              sELECT 0

              UNION ALL

              SELECT N+1  FROM R

              WHERE N < 100 )

              SELECT DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE()))

              + ' ' + CONVERT(VARCHAR(4),DATEPART(Day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,-N,GETDATE()))+1,0))))

              + ', ' + CAST(DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE())) AS VARCHAR(4)) AS Display

              , CONVERT(VARCHAR(4),DATEPART(MONTH,DATEADD(MONTH,-N,GETDATE())))

               + '/'

               + CONVERT(VARCHAR(4),DATEPART(Day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,DATEADD(MONTH,-N,GETDATE()))+1,0))))

               +'/' + CONVERT(VARCHAR(4),DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE()))) 

               AS [Value]

              FROM R

       end

else

       begin

              --Display                                Value

              ---------------------------------------- -----------

              --February 1, 2012                       2/1/2012

              --January 1, 2012                        1/1/2012

              --December 1, 2011                       12/1/2011

              WITH R(N) AS (

              sELECT 0

              UNION ALL

              SELECT N+1  FROM R

              WHERE N < 100 )

              SELECT DATENAME(MONTH,DATEADD(MONTH,-N,GETDATE())) + ' 1, ' +

                CAST(DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE())) AS VARCHAR(4)) AS Display

              , CONVERT(VARCHAR(4),DATEPART(MONTH,DATEADD(MONTH,-N,GETDATE())))

               + '/1/' + CONVERT(VARCHAR(4),DATEPART(YEAR,DATEADD(MONTH,-N,GETDATE()))) 

               AS [Value]

              FROM R

       end

Thursday, January 12, 2012

Generate insert SQL for a table

Thanks to

Andraax
Aged Yak Warrior

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=23133

 

Generate insert SQL for a table - Insert this stored proc:

 

create

proc [dbo].[generate_inserts] @table varchar(50)

--Generate inserts for table @table

AS

declare

@cols varchar(1000)

declare

@col varchar(50)

/*

generate_inserts 'PlanLevel1ControlResponsibility'

*/

set

@cols=''

declare

colcur

cursor

for

select

column_name

from

information_schema.columns

where

table_name=@table

open

colcur

fetch

next from colcur into @col

while

@@fetch_status=0

begin

select

@cols = @cols + ', ' + @col

fetch

next from colcur into @col

end

close

colcur

deallocate

colcur

select

@cols = substring(@cols, 3, datalength(@cols))

--select @cols

declare

@sql varchar(4000)

declare

@colname varchar(100),

@coltype

varchar(30)

select

@sql = 'select replace(''insert ' + @table + ' (' + @cols + ') '

select

@sql = @sql + 'values ('''

declare

ccur

cursor

for

select

column_name, data_type

from

information_schema.columns

where

table_name=@table

open

ccur

fetch

from ccur into @colname, @coltype

while

@@fetch_status=0

begin

if

@coltype in ('varchar', 'char', 'datetime')

select

@sql=@sql + ''''''

select

@sql=@sql + ' + coalesce(convert(varchar, ' + @colname + '), ''null'') + '

if

@coltype in ('varchar', 'char', 'datetime')

select

@sql=@sql + ''''''

select

@sql = @sql + ''', '''

fetch

from ccur into @colname, @coltype

end

close

ccur

deallocate

ccur

select

@sql=substring(@sql, 1, datalength(@sql)-3)

select

@sql=@sql + ')'', ''''''null'''''', ''null'') from ' + @table

exec

(@sql)

GO

 

 

 

 

Sunday, January 08, 2012

list schema, table, row count in a database

-----------------------------------------------------------

--all info from Tables

-----------------------------------------------------------

SELECT

*

FROM

sys.Tables

-----------------------------------------------------------

--Schema.name from Tables

-----------------------------------------------------------

SELECT

'['+SCHEMA_NAME(schema_id)+'].['+name+']'

AS

SchemaTable

FROM

sys.tables

-----------------------------------------------------------

--Schema, name from Tables

-----------------------------------------------------------

SELECT

SCHEMA_NAME(schema_id) [Schema]

,

name [Table]

FROM

sys.tables

-----------------------------------------------------------

--(for dropdownlist) Schema.name - rowcount, Schema.name from Tables

-----------------------------------------------------------

select

--'['+SCHEMA_NAME(t.[SCHEMA_ID])+'].['+t.NAME+']' AS [fulltable_name],

SCHEMA_NAME

(t.[SCHEMA_ID]) as [schema_name],t.NAME as [table_name] ,i.rows

from

sys.tables t

INNER

JOIN sysindexes i ON (t.object_id = i.id AND i.indid < 2)

SELECT

[TableAndCount]

= '['+SCHEMA_NAME(t.[SCHEMA_ID])+'].['+t.NAME+']' + ' - ' + CAST(i.rows as varchar(10)) + ' Rows',

[Name]

= '['+SCHEMA_NAME(t.[SCHEMA_ID])+'].['+t.NAME+']'

--[RowCount] = MAX(si.rows)

FROM

sys.tables t

INNER JOIN sysindexes i ON (t.object_id = i.id AND i.indid < 2)

ORDER

BY

'['+SCHEMA_NAME(t.[SCHEMA_ID])+'].['+t.NAME+']'

Thursday, December 15, 2011

Display Foreign Key Relationships and Name of the Constraint for Each Table in Database

Display Foreign Key Relationships and Name of the Constraint for Each Table in Database

 

Original Article:  http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-foreign-key-relationships-and-name-of-the-constraint-for-each-table-in-database/

 

I changed to version below to

1) show PK to the left

2) trim the result columns

 

SELECT

PK_Table =Left(PK.TABLE_NAME, 35),

PK_Column =Left(PT.COLUMN_NAME, 12),

FK_Table =Left(FK.TABLE_NAME, 25),

FK_Column =Left(CU.COLUMN_NAME, 20),

Constraint_Name = C.CONSTRAINT_NAME

FROM INFORMATION_SCHEMA . REFERENTIAL_CONSTRAINTS C

INNER JOIN INFORMATION_SCHEMA . TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME

INNER JOIN INFORMATION_SCHEMA . TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME

INNER JOIN INFORMATION_SCHEMA . KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME

INNER JOIN (

SELECT i1.TABLE_NAME, i2.COLUMN_NAME

FROM INFORMATION_SCHEMA . TABLE_CONSTRAINTS i1

INNER JOIN INFORMATION_SCHEMA . KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME

WHERE i1.CONSTRAINT_TYPE ='PRIMARY KEY'

) PT ON PT.TABLE_NAME = PK.TABLE_NAME

---- optional:

ORDER BY

--1,2,3,4

PK_Table, FK_Table

--WHERE PK.TABLE_NAME='something'WHERE FK.TABLE_NAME='something'

--WHERE PK.TABLE_NAME IN ('one_thing', 'another')

--WHERE FK.TABLE_NAME IN ('one_thing', 'another')

 

Friday, November 11, 2011

FTP Upload ftpWebRequest Proxy

Searchable:
 
FTP Upload ftpWebRequest Proxy
FTP command is not supported when using HTTP proxy

 

 
In the article below I will cover 2 topics
 
1.       C# & Windows Command-Line FTP Upload with No Proxy Server
 
2.       C# & Windows Command-Line FTP Upload with Proxy Server
 
Not covered here: Secure FTP / SFTP
 
Sample Attributes:
·         UploadFilePath = “\\servername\folder\file.name
·         Proxy Server = ftp://proxy.server/
·         FTP Target Server = ftp.target.com
·         FTP User = “User”
·         FTP Password = “Password”
with No Proxy Server
·         Windows Command-Line
> ftp User: User
> ftp Password: Password
> ftp dir
          (result: file.name listed)
> ftp del file.name
> ftp dir
          (result: file.name deleted)
> ftp quit
 
·         C#
 
//-----------------
//Start FTP via _TargetFtpProxy
//-----------------
string relPath = Path.GetFileName(\\servername\folder\file.name);
 
//result: relPath = “file.name”
 
FtpWebRequest ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp.target.com/file.name);
ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
 
//-----------------
//user - password
//-----------------
ftpWebRequest.Credentials = new NetworkCredential("user, "password");
 
//-----------------
// set proxy = null!
//-----------------
ftpWebRequest.Proxy = null;
 
//-----------------
// Copy the contents of the file to the request stream.
//-----------------
StreamReader sourceStream = new StreamReader(“\\servername\folder\file.name);
 
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
ftpWebRequest.ContentLength = fileContents.Length;
 
 
//-----------------
// transer the stream stream.
//-----------------
Stream requestStream = ftpWebRequest.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
 
//-----------------
// Look at the response results
//-----------------
FtpWebResponse response = (FtpWebResponse)ftpWebRequest.GetResponse();
 
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
 
with Proxy Server
·         Windows Command-Line
> ftp proxy.server
> ftp User: User@ftp.target.com
> ftp Password: Password
> ftp dir
          (result: file.name listed)
> ftp del file.name
> ftp dir
          (result: file.name deleted)
> ftp quit
 
·         C#
 
//-----------------
//Start FTP via _TargetFtpProxy
//-----------------
string relPath = Path.GetFileName(\\servername\folder\file.name);
 
//result: relPath = “file.name”
 
FtpWebRequest ftpWebRequest = (FtpWebRequest)WebRequest.Create("ftp://proxy.server/" + relPath);
ftpWebRequest.Method = WebRequestMethods.Ftp.UploadFile;
 
//-----------------
//user - password
//-----------------
ftpWebRequest.Credentials = new NetworkCredential("user@ftp.target.com, "password");
 
//-----------------
// set proxy = null!
//-----------------
ftpWebRequest.Proxy = null;
 
//-----------------
// Copy the contents of the file to the request stream.
//-----------------
StreamReader sourceStream = new StreamReader(“\\servername\folder\file.name);
 
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
ftpWebRequest.ContentLength = fileContents.Length;
 
 
//-----------------
// transer the stream stream.
//-----------------
Stream requestStream = ftpWebRequest.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
 
//-----------------
// Look at the response results
//-----------------
FtpWebResponse response = (FtpWebResponse)ftpWebRequest.GetResponse();
 
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);

Friday, October 14, 2011

Invalid value for 'OSVersion'

Invalid value for 'OSVersion'

 Thanks to Mike Wade @ Microsoft

I would recommend clearing the environment variable, or better yet, adding the following to the project file:

  <PropertyGroup>
    <OSVersion></OSVersion>
  </PropertyGroup>

This will fully override the environment variable and blank it out.  The task should then set this to a better default value.

Monday, October 10, 2011

Oracle Dynamic SQL – Drop Table, Copy Table, Purge Tables

Oracle Dynamic SQL – Drop Table, Copy Table, Purge Tables       
 
 
CREATEORREPLACEPROCEDURE COMPLIANCE11.table_drop (table_name VARCHAR2) IS
    dml_str
VARCHAR2        (500);
BEGIN
    dml_str :=
'DROP TABLE ' || table_name ;
   
EXECUTEIMMEDIATE dml_str ;
END;
 
 
 
void the_Table_Housekeeping()
        {
            try
            {
 
                string JobDateTime_string = _jobDateTime.ToString("yyyy-MM-dd_HH-mm-ss");
                JobDateTime_string = JobDateTime_string.Replace("-", "");
                JobDateTime_string = JobDateTime_string.Replace("_", "");
 
                Microsoft_Enterprise_Library.Oracle.OracleAccessLayer objData = new Microsoft_Enterprise_Library.Oracle.OracleAccessLayer();
 
 
                //-----------------------------------
                // look for dupe table before drop table
                //-----------------------------------
 
                string ssql = "select nvl((select 1 from user_tables where table_name='THE_" + JobDateTime_string + "' and rownum=1),0) from dual";
                DataTable dt = objData.GetDataTableFromOracleSQL(ssql, this._Oracle_Compliance11connectionString);
                if (dt.Rows.Count < 1)
                {
                    throw new Exception("dt.Rows.Count < 1");
                }
                int found = int.Parse(dt.Rows[0][0].ToString());
 
                OracleCommand oracleCommand = new OracleCommand();
                if (found == 1)
                {
                    //-----------------------------------
                    // drop table
                    //-----------------------------------
                    oracleCommand.CommandText = "table_Drop";
                    oracleCommand.Parameters.Clear();
                    oracleCommand.Parameters.Add("table_name", OracleType.VarChar).Value = "THE_" + JobDateTime_string;
                    int rowsAffected = objData.GetRowsAffected_From_StoredProc(this._Oracle_Compliance11connectionString,
                                                                                oracleCommand);
                }
 
                //-----------------------------------
                // does not work, "insufficient privileges"
                //-----------------------------------
                //oracleCommand.CommandText = "table_copy";
                //oracleCommand.Parameters.Clear();
                //oracleCommand.CommandType = CommandType.StoredProcedure;
                //oracleCommand.Parameters.Add("table_name_orig", OracleType.VarChar).Value = "THE_Table";
                //oracleCommand.Parameters.Add("table_name_new", OracleType.VarChar).Value = "THE_" + JobDateTime_string;
                //int rowsAffected2 = objOracle.GetRowsAffected_From_StoredProc_Transaction();
 
                //-----------------------------------
                // create table
                //-----------------------------------
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("CREATE TABLE THE_" + JobDateTime_string + " AS (SELECT * FROM THE_Table)");
                string mySQL = sb.ToString();
                oracleCommand.CommandType = CommandType.Text;
                int rowsAffected2 = objData.ExecuteNonQuery_SQL(
                                                mySQL,
                                                this._Oracle_Compliance11connectionString,
                                                false);
 
                //-----------------------------------
                // purge to 4 previous copies
                //-----------------------------------
                sb = new StringBuilder();
                ssql = "select table_name from user_tables where table_name LIKE 'THE_2%' order by table_name asc";
                dt = objData.GetDataTableFromOracleSQL(ssql, this._Oracle_Compliance11connectionString);
 
                for (int i = 0; i < dt.Rows.Count - 4; i++)
                {
                    string table_name = dt.Rows[i][0].ToString();
                    //-----------------------------------
                    // drop table
                    //-----------------------------------
                    oracleCommand.CommandText = "table_Drop";
                    oracleCommand.Parameters.Clear();
                    oracleCommand.Parameters.Add("table_name", OracleType.VarChar).Value = table_name;
                    int rowsAffected = objData.GetRowsAffected_From_StoredProc(this._Oracle_Compliance11connectionString,
                                                                                oracleCommand); ;
                }
 
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
 
 

Thursday, October 06, 2011

OpenXML SDK 2.0: Export a DataTable to Excel

OpenXML SDK 2.0: Export a DataTable to Excel

Very good article and download project

http://lateral8.com/articles/2010/3/5/openxml-sdk-20-export-a-datatable-to-excel.aspx

 

The DocumentFormat.OpenXml.dll is registered in the GAC when the SDK is installed so it doesn't physically copy it to your project's output folder by default when you build the application.  If you select the option to Show All Files in Visual Studio (Project | Show All Files), you'll see a References node appear in your VB.NET project in the Solution Explorer.  Expand it, select DocumentFormat.OpenXml, view it's properties, and set the Copy Local option to True so that it copies it to the output folder when you build the app.  You can then copy it along with the app to any other PC and it will run without having to install the SDK on them.

 

Wednesday, August 10, 2011

Debug Web Part installed in GAC

Debug Web Part installed in GAC

Thanks to  Doug Ware @ Elumenotion > Elumenotion Blog > Posts > You Don't Need to Copy PDB Files to Debug in the GAC!
11/12/2007
 
 

Thursday, July 28, 2011

ASP.NET Detect and alert forms authentication timeout

ASP.NET Detect and alert forms authentication timeout
 
1.      Add sessionState to web.config
 <system.web>
        <sessionStatetimeout="1"mode="InProc" /> <!--minutes e.g. 120 = 2 hours-->
 
2.      Add  FormsAuthentication to web.config
    <authenticationmode="Forms">
      <!--timeout minutes (needs to be the same as in sessionState above) e.g. 120 = 2 hours-->
      <!--loginUrl - destination when FormsAuthentication Times out -->
      <!--defaultUrl - where FormsAuthentication.RedirectFromLoginPage goes, unless user overrode with valid URL in browser-->
      <formsloginUrl="~/Forms/Logon.aspx"                        
             defaultUrl="~/Forms/OrderCreate.aspx?TimeOut=True"
             protection="All"
             timeout="1"
             name=".ASPXAUTH"
             path="/"
             requireSSL="false"
             slidingExpiration="true"
             cookieless="UseDeviceProfile"
             enableCrossAppRedirects="false"/>
    </authentication>
 
3.      On Session_Start, detect session timeout and set a “CatchTimeOut” session variable
 void Session_Start(object sender, EventArgs e)
    {
        // Code that runs when a new session is started
        // no - Response.Cookies["CoprSession"].Value = ""; //.Expires = DateTime.Now.AddDays(5000);
 
 
        //This is obviously a new session being created; it can be
        //created at the first hit of a user, or when the user
        //previous session has expired (timeout). We are only interested
        //in the timeout scenario, so we look at the request cookies
        //and if we have a previous session ID cookie, it means this is a
        //new session due to the timing out of the old one.
        //Note: slight problem here: in .Net 2.0 the ASP Session ID
        //cookie name is configurable, but we don't have a way to
        //retrieve that from the web.config - so if you customize
        //the session cookie name in the web.config you'll have to
        //use the same name here.
        string request_cookies = Request.Headers["Cookie"];
        if ((null != request_cookies) &&
                (request_cookies.IndexOf("ASP.NET_SessionId") >= 0))
        {
            //cookie existed, so this new one is due to timeout.
            //Redirect the user to the login page
            //System.Diagnostics.Debug.WriteLine("Session expired!");
 
            //Response.Redirect(Constants.HOME_PAGE + "?" +
 
            //                  Constants.PARAM_REQUEST + "=" +
 
            //                  Constants.PARAM_REQUEST_VALUE_TIMEOUT);
            Session[“CatchTimeOut”] = true;
        }
    }
4.      Create a base page to query the “CatchTimeOut” session variable and do a javascript alert
public class _BasePage : System.Web.UI.Page
{
    protected override void OnLoad(EventArgs e)
    {
 
        // Be sure to call the base class's OnLoad method!
        base.OnLoad(e);
 
 
        //-----------------------------------------------------------------------
        //
        //-----------------------------------------------------------------------
        if (Session[“CatchTimeOut”])
        {
            Session[“CatchTimeOut”] = false;
            string strScript = "<script>alert('Your web session timed out.');</script>";
            Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "ShowInfo", strScript);
        }
    }
}
5.      Inherit base page wherever base behavior is needed
·         public partial class LnumberSearch : _BasePage
·        {
 

Wednesday, April 13, 2011

Capture DataGridView CheckBox Checked event on a WinForm

 

 

    Private Sub dgv_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dgv.CurrentCellDirtyStateChanged

        '--------------------------------------------------------

        'when a user checks/unchecks a checkbox

        'perform "commitEdit" so that "CellValueChanged" event gets fired

        '--------------------------------------------------------

        If dgv.IsCurrentCellDirty Then

            dgv.CommitEdit(DataGridViewDataErrorContexts.Commit)

        End If

 

    End Sub

 

    Private Sub dgv_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgv.CellValueChanged

 

        '--------------------------------------------------------

        'when a user checks/unchecks a checkbox

        'be sure to check/uncheck other rows with same session, barcode and assay (but different seq)

        '--------------------------------------------------------

        Dim checked As Boolean = Boolean.Parse(dgv.CurrentRow.Cells(gCol.PlateIsLabeled).Value.ToString) = True

        Dim targetSessionName As String = dgv.CurrentRow.Cells(gCol.SessionName).Value.ToString

        Dim targetPlateBarcode As String = dgv.CurrentRow.Cells(gCol.PlateBarcode).Value.ToString

        Dim targetAssayName As String = dgv.CurrentRow.Cells(gCol.AssayName).Value.ToString

        For Each irow As DataGridViewRow In dgv.Rows

            If irow.Index <> dgv.CurrentRow.Index Then

                Dim PlateBarcode As String = irow.Cells(gCol.PlateBarcode).Value.ToString

                Dim AssayName As String = irow.Cells(gCol.AssayName).Value.ToString

                Dim SessionName As String = irow.Cells(gCol.SessionName).Value.ToString

                If PlateBarcode = targetPlateBarcode _

                And AssayName = targetAssayName _

                And SessionName = targetSessionName _

                Then

                    irow.Cells(gCol.PlateIsLabeled).Value = checked

                End If

            End If

        Next

 

    End Sub

Capture DataGridView CheckBox Checked event on a WinForm

Friday, March 25, 2011

ASP.NET Export n GridViews to Excel

ASP.NET Export n GridViews to Excel
 
Thanks to awesome article by Matt Berseth
 
//Web Page Call to ExcelExport Class
 
    protected void lnkExport_Click(object sender, EventArgs e)
    {
        //creating the array of GridViews and calling the Export function
        GridView[] gvList = new GridView[] { gvPlateList, gvPlateDetails };
        ExcelExport.Export("DeliverySheet.xls", gvList);
    }
 
//ExcelExport Class
 
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
///<summary>
/// Summary description for ExcelExport
///</summary>
public static class ExcelExport
{
    public static void Export(string fileName, GridView[] gvs)
    {
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", fileName));
        HttpContext.Current.Response.ContentType = "application/ms-excel";
        System.IO.StringWriter sw = new System.IO.StringWriter();
        HtmlTextWriter htw = new HtmlTextWriter(sw);
 
        foreach (GridView gv in gvs)
        {
            //   Create a form to contain the grid
            Table table = new Table();
            table.GridLines = gv.GridLines;
            //   add the header row to the table
            if (!(gv.HeaderRow == null))
            {
                PrepareControlForExport(gv.HeaderRow);
                table.Rows.Add(gv.HeaderRow);
            }
            //   add each of the data rows to the table
            foreach (GridViewRow row in gv.Rows)
            {
                PrepareControlForExport(row);
                table.Rows.Add(row);
            }
            //   add the footer row to the table
            if (!(gv.FooterRow == null))
            {
                PrepareControlForExport(gv.FooterRow);
                table.Rows.Add(gv.FooterRow);
            }
            //   render the table into the htmlwriter
            table.RenderControl(htw);
        }
        //   render the htmlwriter into the response
        HttpContext.Current.Response.Write(sw.ToString());
        HttpContext.Current.Response.End();
    }
 
    private static void PrepareControlForExport(Control control)
    {
        for (int i = 0; i < control.Controls.Count; i++)
        {
            Control current = control.Controls[i];
            if (current is LinkButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
            }
            else if (current is ImageButton)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
            }
            else if (current is HyperLink)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
            }
            else if (current is DropDownList)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
            }
            else if (current is CheckBox)
            {
                control.Controls.Remove(current);
                control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
            }
 
            if (current.HasControls())
            {
                PrepareControlForExport(current);
            }
        }
    }
}
 
 

Tuesday, March 01, 2011

ASP.NET Conditionally Change ButtonField text at runTime

ASP.NET Conditionally Change ButtonField text at runTime
 
<asp:ButtonField CommandName="Edit" HeaderText="" Text="Edit" ButtonType="Link" />
  
 
 protected void gvRequests_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            //----------------------------------------------------
            // If status = "Saved", change buttonField.LinkButton.Text to "Copy"
            //----------------------------------------------------
            if (e.Row.Cells[(int)gCol.Status].Text == "Saved")
            {
                //----------------------------------------------------
                // no !
                //----------------------------------------------------
                //string x = e.Row.Cells[(int)gCol.EditLink].Text;
                //e.Row.Cells[(int)gCol.EditLink].Text = "Copy";
 
                //----------------------------------------------------
                // yes !
                //----------------------------------------------------
                LinkButton linkButton = (LinkButton)e.Row.Cells[(int)gCol.EditLink].Controls[0];
                linkButton.Text = "Copy";
            }
        }
    }

Saturday, February 26, 2011

SQL Server Interview Questions

User-Defined Functions

Scalar User-Defined Function

A Scalar user-defined function returns one of the scalar data types. Text, ntext, image and timestamp data types are not supported. These are the type of user-defined functions that most developers are used to in other programming languages.

Table-Value User-Defined Function

An Inline Table-Value user-defined function returns a table data type and is an exceptional alternative to a view as the user-defined function can pass parameters into a T-SQL select command and in essence provide us with a parameterized, non-updateable view of the underlying tables.

Multi-statement Table-Value User-Defined Function

A Multi-Statement Table-Value user-defined function returns a table and is also an exceptional alternative to a view as the function can support multiple T-SQL statements to build the final result where the view is limited to a single SELECT statement. Also, the ability to pass parameters into a T-SQL select command or a group of them gives us the capability to in essence create a parameterized, non-updateable view of the data in the underlying tables. Within the create function command you must define the table structure that is being returned. After creating this type of user-defined function, I can use it in the FROM clause of a T-SQL command unlike the behavior found when using a stored procedure which can also return record sets.

CREATE FUNCTION dbo.customersbycountry ( @Country varchar(15) )

RETURNS

        @CustomersbyCountryTab table (

               [CustomerID] [nchar] (5), [CompanyName] [nvarchar] (40),

               [ContactName] [nvarchar] (30), [ContactTitle] [nvarchar] (30),

               [Address] [nvarchar] (60), [City] [nvarchar] (15),

               [PostalCode] [nvarchar] (10), [Country] [nvarchar] (15),

               [Phone] [nvarchar] (24), [Fax] [nvarchar] (24)

        )

AS

BEGIN

        INSERT INTO @CustomersByCountryTab

        SELECT [CustomerID],

                       [CompanyName],

                       [ContactName],

                       [ContactTitle],

                       [Address],

                       [City],

                       [PostalCode],

                       [Country],

                       [Phone],

                       [Fax]

        FROM [Northwind].[dbo].[Customers]

        WHERE country = @Country

       

        DECLARE @cnt INT

        SELECT @cnt = COUNT(*) FROM @customersbyCountryTab

       

        IF @cnt = 0

               INSERT INTO @CustomersByCountryTab (

                       [CustomerID],

                       [CompanyName],

                       [ContactName],

                       [ContactTitle],

                       [Address],

                       [City],

                       [PostalCode],

                       [Country],

                       [Phone],

                       [Fax]  )

               VALUES ('','No Companies Found','','','','','','','','')

       

        RETURN

END

GO

SELECT * FROM dbo.customersbycountry('USA')

SELECT * FROM dbo.customersbycountry('CANADA')

SELECT * FROM dbo.customersbycountry('ADF')

User Defined Functions (UDF) Limitations

UDF have its own advantage and usage but in this article we will see the limitation of UDF. Things UDF can not do and why Stored Procedure are considered as more flexible then UDFs. Stored Procedure are more flexibility then User Defined Functions(UDF).

  • UDF has No Access to Structural and Permanent Tables.
    • UDF can call Extended Stored Procedure, which can have access to structural and permanent tables. (No Access to Stored Procedure)
  • UDF Accepts Lesser Numbers of Input Parameters.
    • UDF can have upto 1023 input parameters, Stored Procedure can have upto 21000 input parameters.
  • UDF Prohibit Usage of Non-Deterministic Built-in Functions
    • Functions GETDATE() etc can not be used UDFs, but can be used in Stored Procedure
  • UDF Returns Only One Result Set or Output Parameter
    • Due to this it can be used in SELECT statement but can not return multiple result set like Stored Procedure
  • UDF can not Call Stored Procedure
    • Only access to Extended Stored Procedure.
  • UDF can not Execute Dynamic SQL or Temporary Tables
    • UDF can not run dynamic SQL which are dynamically build in UDF. Temporary Tables can not be used in UDF as well.
  • UDF can not Return XML
    • FOR XML is not allowed in UDF
  • UDF does not support SET options
    • SET options which can change Server level or transaction level settings are prohibited in UDFs. (SET ROWCOUNT etc)
  • UDF does not Support Error Handling
    • RAISEERROR or @@ERROR are not allowed in UDFs.

 

CREATE FUNCTION whichContinent

Isolation Levels

SET TRANSACTION ISOLATION LEVEL

    { READ UNCOMMITTED

    | READ COMMITTED

    | REPEATABLE READ

    | SNAPSHOT

    | SERIALIZABLE

    }

[ ; ]

 

READ UNCOMMITTED

Specifies that statements can read rows that have been modified by other transactions but not yet committed.

Nonrepeatabel read: If somebody performed UPDATE or DELETE of any of the rows you read earlier.

Phantom: If anybody INSERTed a row within the range you had for an earlier query (i.e., you see new rows).

READ COMMITTED

Specifies that statements can only read data that has been committed by other transactions. This prevents dirty reads. Data can be changed by other transactions between individual statements within the current transaction, resulting in nonrepeatable reads or phantom data. This option is the SQL Server default.

REPEATABLE READ

Specifies that statements cannot read data that has been modified but not yet committed by other transactions and that no other transactions can modify data that has been read by the current transaction until the current transaction completes.

SNAPSHOT

Specifies that data read by any statement in a transaction will be the transactionally consistent version of the data that existed at the start of the transaction. The transaction can only recognize data modifications that were committed before the start of the transaction. Data modifications made by other transactions after the start of the current transaction are not visible to statements executing in the current transaction. The effect is as if the statements in a transaction get a snapshot of the committed data as it existed at the start of the transaction.

SERIALIZABLE

Specifies the following:

·         Statements cannot read data that has been modified but not yet committed by other transactions.

·         No other transactions can modify data that has been read by the current transaction until the current transaction completes.

·         Other transactions cannot insert new rows with key values that would fall in the range of keys read by any statements in the current transaction until the current transaction completes.

Lock types

There are three main types of locks that SQL Server 7.0/2000 uses:

·  Shared locks

·  Update locks

·  Exclusive locks

Shared locks are used for operations
that do not change or update data, such as a SELECT statement.

Update locks are used when SQL Server intends to modify a page, and later promotes the update page lock to an exclusive page lock before actually making the changes.

Exclusive locks are used for the data modification operations, such as UPDATE, INSERT, or DELETE.

Shared locks are compatible with other Shared locks or Update locks.

Update locks are compatible with Shared locks only.

Exclusive locks are not compatible with other lock types.

 

Deadlocks

ways to avoid cursors include:

  • Rewriting the cursor as a normal query. Some people write cursors that perform the same task over and over on a set of records. This is a waste of server resources because this could be easily handled by a standard query. And even if what you need to do to each row is conditional on data in a row, you still may be able to to use a standard query using a CASE statement.
  • Rewriting the cursor as a derived query. See this article for more information.
  • Rewriting the cursor using temporary tables in a query. See this article for more information.
  • Rewriting the cursor using table variables in a query (SQL Server 2000 or 2005).

joins options in SQL Server:

  • INNER JOIN - Match rows between the two tables specified in the INNER JOIN statement based on one or more columns having matching data.  Preferably the join is based on referential integrity enforcing the relationship between the tables to ensure data integrity.
    • Just to add a little commentary to the basic definitions above, in general the INNER JOIN option is considered to be the most common join needed in applications and/or queries.  Although that is the case in some environments, it is really dependent on the database design, referential integrity and data needed for the application.  As such, please take the time to understand the data being requested then select the proper join option.
    • Although most join logic is based on matching values between the two columns specified, it is possible to also include logic using greater than, less than, not equals, etc.
  • LEFT OUTER JOIN - Based on the two tables specified in the join clause, all data is returned from the left table.  On the right table, the matching data is returned in addition to NULL values where a record exists in the left table, but not in the right table.
    • Another item to keep in mind is that the LEFT and RIGHT OUTER JOIN logic is opposite of one another.  So you can change either the order of the tables in the specific join statement or change the JOIN from left to right or vice versa and get the same results.
  • RIGHT OUTER JOIN - Based on the two tables specified in the join clause, all data is returned from the right table.  On the left table, the matching data is returned in addition to NULL values where a record exists in the right table but not in the left table.
  • Self -Join - In this circumstance, the same table is specified twice with two different aliases in order to match the data within the same table.
  • CROSS JOIN - Based on the two tables specified in the join clause, a Cartesian product is created if a WHERE clause does filter the rows.  The size of the Cartesian product is based on multiplying the number of rows from the left table by the number of rows in the right table.  Please heed caution when using a CROSS JOIN.
  • FULL JOIN - Based on the two tables specified in the join clause, all data is returned from both tables regardless of matching data.

Stored Proc Error Handling

 

Fatal Error

 

SELECT * FROM NonExistentTable

 

 

Non Fatal

INSERT a row into table and omit a column

 

RAISERROR ( { msg_id | msg_str | @local_variable }

    { ,severity ,state }

    [ ,argument [ ,...n ] ] )

    [ WITH option [ ,...n ] ]

 

Uncommittable Transactions and XACT_STATE

If an error generated in a TRY block causes the state of the current transaction to be invalidated, the transaction is classified as an uncommittable transaction. An error that ordinarily ends a transaction outside a TRY block causes a transaction to enter an uncommittable state when the error occurs inside a TRY block. An uncommittable transaction can only perform read operations or a ROLLBACK TRANSACTION. The transaction cannot execute any Transact-SQL statements that would generate a write operation or a COMMIT TRANSACTION. The XACT_STATE function returns a value of -1 if a transaction has been classified as an uncommittable transaction. When a batch finishes, the Database Engine rolls back any active uncommittable transactions. If no error message was sent when the transaction entered an uncommittable state, when the batch finishes, an error message will be sent to the client application. This indicates that an uncommittable transaction was detected and rolled back.

Using TRY…CATCH with XACT_STATE

The following example shows how to use the TRY…CATCH construct to handle errors that occur inside a transaction. The XACT_STATE function determines whether the transaction should be committed or rolled back. In this example, SET XACT_ABORT is ON. This makes the transaction uncommittable when the constraint violation error occurs.

Copy

USE AdventureWorks2008R2;

GO

 

-- Check to see whether this stored procedure exists.

IF OBJECT_ID (N'usp_GetErrorInfo', N'P') IS NOT NULL

    DROP PROCEDURE usp_GetErrorInfo;

GO

 

-- Create procedure to retrieve error information.

CREATE PROCEDURE usp_GetErrorInfo

AS

    SELECT

        ERROR_NUMBER() AS ErrorNumber

        ,ERROR_SEVERITY() AS ErrorSeverity

        ,ERROR_STATE() AS ErrorState

        ,ERROR_LINE () AS ErrorLine

        ,ERROR_PROCEDURE() AS ErrorProcedure

        ,ERROR_MESSAGE() AS ErrorMessage;

GO

 

-- SET XACT_ABORT ON will cause the transaction to be uncommittable

-- when the constraint violation occurs.

SET XACT_ABORT ON;

 

BEGIN TRY

    BEGIN TRANSACTION;

        -- A FOREIGN KEY constraint exists on this table. This

        -- statement will generate a constraint violation error.

        DELETE FROM Production.Product

            WHERE ProductID = 980;

 

    -- If the DELETE statement succeeds, commit the transaction.

    COMMIT TRANSACTION;

END TRY

BEGIN CATCH

    -- Execute error retrieval routine.

    EXECUTE usp_GetErrorInfo;

 

    -- Test XACT_STATE:

        -- If 1, the transaction is committable.

        -- If -1, the transaction is uncommittable and should

        --     be rolled back.

        -- XACT_STATE = 0 means that there is no transaction and

        --     a commit or rollback operation would generate an error.

 

    -- Test whether the transaction is uncommittable.

    IF (XACT_STATE()) = -1

    BEGIN

        PRINT

            N'The transaction is in an uncommittable state.' +

            'Rolling back transaction.'

        ROLLBACK TRANSACTION;

    END;

 

    -- Test whether the transaction is committable.

    IF (XACT_STATE()) = 1

    BEGIN

        PRINT

            N'The transaction is committable.' +

            'Committing transaction.'

        COMMIT TRANSACTION;  

    END;

END CATCH;

GO

 

Temporary Tables vs. Table Variables and Their Effect on SQL Server Performance

 

http://www.sql-server-performance.com/articles/per/temp_tables_vs_variables_p1.aspx

There are three major theoretical differences between temporary tables:

create table #T (…)

And table variables:

declare @T table (…)

1.      transaction logs are not recorded for the table variables. Hence, they are out of scope of the transaction mechanism, i.e. table variable updates within a transaction cannot be rolled back

a.       table variables no transactions

2.      temporary table cannot be pre-compiled, while an execution plan of procedures with table variables can be statically compiled in advance. Pre-compiling a script gives a major advantage to its speed of execution. This advantage can be dramatic for long procedures, where recompilation can be too pricy

a.       table variables can be pre-compiled execution plan

3.      table variables exist only in the same scope as variables. Contrary to the temporary tables, they are not visible in inner stored procedures and in exec(string) statements. Also, they cannot be used in an insert/exec statement.

a.       table variables limited scope

PIVOT and UNPIVOT Table Examples

 

http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/

 

n        Creating Test Table
CREATE TABLE Product(Cust VARCHAR(25), Product VARCHAR(20), QTY INT)
GO
-- Inserting Data into Table
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','VEG',2)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','SODA',6)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','MILK',1)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','BEER',12)
INSERT INTO Product(Cust, Product, QTY)
VALUES('FRED','MILK',3)
INSERT INTO Product(Cust, Product, QTY)
VALUES('FRED','BEER',24)
INSERT INTO Product(Cust, Product, QTY)
VALUES('KATE','VEG',3)
GO

 

Pivot Table ordered by CUST
SELECT CUST, VEG, SODA, MILK, BEER, CHIPS
FROM (
SELECT CUST, PRODUCT, QTY
FROM Product) up
PIVOT
(SUM(QTY) FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)) AS pvt
ORDER BY CUST
GO
-- Unpivot Table ordered by CUST
SELECT CUST, PRODUCT, QTY
FROM
(
SELECT CUST, VEG, SODA, MILK, BEER, CHIPS
FROM (
SELECT CUST, PRODUCT, QTY
FROM Product) up
PIVOT
( SUM(QTY) FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)) AS pvt) p
UNPIVOT
(QTY FOR PRODUCT IN (VEG, SODA, MILK, BEER, CHIPS)
)
AS Unpvt
GO

 

Tips on Optimizing Covering Indexes

By : Brad McGehee
Jan 19, 2007

 

 

If you have to use a non-clustered index (because your single clustered index can be used better elsewhere in a table), and if you know that your application will be performing the same query over and over on the same table, consider creating a covering index on the table for the query. A covering index, which is a form of a composite index, includes all of the columns referenced in the SELECT, JOIN, and WHERE clauses of a query. Because of this, the index contains the data you are looking for and SQL Server doesn't have to look up the actual data in the table, reducing logical and/or physical I/O, and boosting performance.

On the other hand, if the covering index gets too big (has too many columns), this could actually increase I/O and degrade performance. Generally, when creating covering indexes, follow these guidelines:

  • If the query or queries you run using the covering index are seldom run, then the overhead of the covering index may outweigh the benefits it provides.
  • The covering index should not add significantly to the size of the key. If it does, then it its use may outweigh the benefits it provides.
  • The covering index must include all columns found in the SELECT list, the JOIN clause, and the WHERE clause.

SQL Server performance tips

 

User Defined Functions (UDF)

Refrain from using user defined functions (UDF) in a select statement that may potentially return many records. UDFs are executed as many times as there are rows in a returned result. A query that returns 100,000 rows calls the UDF 100,000 times.

SQL Server table indexes

Create SQL statements that utilize defined table indexes. Using indexes minimizes the amount of table scan which in most cases will be much slower than an index scan.

Multiple disks

The single best performance increase on a SQL Server computer comes from spreading I/O among multiple drives. Adding memory is a close second. Having many smaller drives is better than having one large drive for SQL Server machines. Even though the seek time is faster in larger drives, you will still get a tremendous performance improvement by spreading files, tables, and logs among more than one drive.

Disk controllers

Different disk controllers and drivers use different amounts of CPU time to perform disk I/O. Efficient controllers and drivers use less time, leaving more processing time available for user applications and increasing overall throughput.

SQL Server foreign keys

Ensure that all your tables are linked with foreign keys. foreign keys enhance the performance of queries with joins. Database tables inside each application are naturally related. Islands of tables are rarely needed if your application's business logic is well defined.

SQL Server primary keys

Ensure that every table has a primary key. if you can't find a natural set of columns to serve as a primary key, create a new column and make it a primary key on the table.

WHERE clause

In a WHERE clause, the various operators used can affect how fast a query is run. This is because some operators lend themselves to speed over other operators. Of course, you may not have any choice of which operator you use in your WHERE clauses, but sometimes you do.

Here are the key operators used in the WHERE clause, ordered by their performance. Those operators at the top will produce results faster than those listed at the bottom.

=

>, >=, <, <=

LIKE

<>

This lesson here is to use = as much as possible, and <> as least as possible. [2000, 2005, 2008] Updated 2-4-2009

*****

In a WHERE clause, the various operands used directly affect how fast a query is run. This is because some operands lend themselves to speed over other operands. Of course, you may not have any choice of which operand you use in your WHERE clauses, but sometimes you do.

Here are the key operands used in the WHERE clause, ordered by their performance. Those operands at the top will produce results faster than those listed at the bottom.

  • A single literal used by itself on one side of an operator.
  • A single column name used by itself on one side of an operator, a single parameter used by itself on one side of an operator.
  • A multi-operand expression on one side of an operator.
  • A single exact number on one side of an operator.
  • Other numeric number (other than exact), date, and time.
  • Character data, NULLs.

The simpler the operand, and using exact numbers, provides the best overall performance. [2000, 2005, 2008] Updated 2-4-2009

*****

If a WHERE clause includes multiple expressions, there is generally no performance benefit gained by ordering the various expressions in a particular order. This is because the SQL Server Query Optimizer automatically orders them (behind the scenes) for optimal performance. There are a few exceptions to this, which are discussed on this web site. [2000, 2005, 2008] Updated 2-4-2009

*****

By default, some developers, especially those who have not worked with SQL Server before, routinely include code similar to this in their WHERE clauses when they make string comparisons:

SELECT column_name FROM table_name

WHERE LOWER(column_name) = 'name'

In other words, these developers are making the assuming that the data in SQL Server is case-sensitive, which it generally is not. If your SQL Server database is not configured to be case sensitive, you don't need to use LOWER or UPPER to force the case of text to be equal for a comparison to be performed. Just leave these functions out of your code. This will speed up the performance of your query, as any use of text functions in a WHERE clause hurts performance.

But what if your database has been configured to be case-sensitive? Should you then use the LOWER and UPPER functions to ensure that comparisons are properly compared? No. The above example is still poor coding. If you have to deal with ensuring case is consistent for proper comparisons, use the technique described below, along with appropriate indexes on the column in question:

SELECT column_name FROM table_name

WHERE column_name = 'NAME' or column_name = 'name'

This code will run much faster than the first example. [2000, 2005, 2008] Updated 2-4-2009

*****

Try to avoid WHERE clauses that are non-sargable. The term "sargable" (which is in effect a made-up word) comes from the pseudo-acronym "SARG", which stands for "Search ARGument," which refers to a WHERE clause that compares a column to a constant value. If a WHERE clause is sargable, this means that it can take advantage of a useful index (assuming one is available) to speed completion of the query. If a WHERE clause is non-sargable, this means that the WHERE clause (or at least part of it) cannot take advantage of an index, instead performing a table/index scan, which may cause the query's performance to suffer.

Non-sargable search arguments in the WHERE clause, such as "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'" generally prevents (but not always) the query optimizer from using a useful index to perform a search. In addition, expressions that include a function on a column, expressions that have the same column on both sides of the operator, or comparisons against a column (not a constant), are not sargable.

But not every WHERE clause that has a non-sargable expression in it is doomed to a table/index scan. If the WHERE clause includes both sargable and non-sargable clauses, then at least the sargable clauses can use a useful index (if one exists) to help access the data quickly.

In many cases, if there is a covering index on the table, which includes all of the columns in the SELECT, JOIN, and WHERE clauses in a query, then the covering index can be used instead of a table/index scan to return a query's data, even if it has a non-sargable WHERE clause. But keep in mind that covering indexes have their own drawbacks, such as potentially producing very wide indexes that increase disk I/O when they are read.

In some cases, it may be possible to rewrite a non-sargable WHERE clause into one that is sargable. For example, the clause:

WHERE SUBSTRING(firstname,1,1) = 'm'

Can be rewritten like this:

WHERE firstname like 'm%'

Both of these WHERE clauses produce the same result, but the first one is non-sargable (it uses a function) and will run slower, while the second one is sargable, and will run much faster.

WHERE clauses that perform some function on a column are non-sargable. On the other hand, if you can rewrite the WHERE clause so that the column and function are separate, then the query can use an available useful index, greatly boosting performance. For example:

Function Acts Directly on Column, and Index Cannot Be Used:

SELECT member_number, first_name, last_name

FROM members

WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21

Function Has Been Separated From Column, and an Index Can Be Used:

SELECT member_number, first_name, last_name

FROM members

WHERE dateofbirth < DATEADD(yy,-21,GETDATE())

Each of the above queries produces the same results, but the second query will use an available, useful index because the function is not performed directly on the column, as it is in the first example. The moral of this story is to try to rewrite WHERE clauses that have functions so that the function does not act directly on the column.

WHERE clauses that use NOT are not sargable, but can often be rewritten to remove the NOT from the WHERE clause, for example:

WHERE NOT column_name > 5

To:

WHERE column_name <= 5

Each of the above clauses produces the same results, but the second one is sargable.

If you don't know if a particular WHERE clause is sargable or non-sargable, check out the query's execution plan in Query Analyzer or Management Studio. Doing this, you can very quickly see if the query uses available indexes as you expect.