navigation
 Tuesday, May 30, 2006

I encountered a troubling message while playing around with SQL Server 2005 and its new Integration Services. It read, “Failed to save package file "C:\Documents and Settings\Adam Anderson\Local Settings\Temp\tmp44F.tmp" with error 0x80029C4A "Error loading type library/DLL.".”

I first saw the error when I tried to create an Integration Services project in Visual Studio 2005, but the project was created anyway. I opened the project and ignored the error, hoping it was merely a glitch. However, after setting up a data source, I tried to add a package, and was blocked by the same error message. Now I knew I was in trouble. This was a brand-new installation, and it was annoying to see such an uninformative message, which is usually a sign that something has gone wrong at a fundamental level. Fortunately, my situation was not unique, and a search on Google quickly brought me to the correct solution.

It turns out that the MSXML 6.0 Parser was either incompletely installed or the installation was damaged.

To fix:

  1. Start Menu | Control Panel | Add or Remove Programs
  2. Locate MSXML 6.0 Parser in the list
  3. Click Change. The Setup dialog will appear.
  4. Click Next.
  5. There will be two options: Repair and Remove. Select Repair, then click Next.
  6. The Setup dialog will display a progress bar and then (hopefully) report success.
posted on May 30, 2006  #    by Adam Anderson  Comments [1] Trackback
 Monday, April 24, 2006

While browsing the web today, I came across a recommendation for Foxit Reader as an alternative to the more well-known Adobe Acrobat Reader. After downloading it and trying it out, I am happy to report that my first impressions of the product are very positive. Some of my biggest causes for discontent with Adobe Acrobat were the sluggish loading times and persistent nagging to upgrade, and both of these are a thing of the past with Foxit. Now when I double-click a PDF file, it opens in the blink of an eye! Farewell, Acrobat. Your slowness and nagging won't be missed.

posted on April 24, 2006  #    by Adam Anderson  Comments [0] Trackback
 Wednesday, April 05, 2006

The SQL Server functions ISNULL and COALESCE seem to occupy the same space in terms of functionality, only ISNULL is restricted to only two parameters, while COALESCE can take any number of parameters. So why ever use ISNULL? Answers and trivia lie within!

First of all, the simple answer for why to prefer ISNULL over COALESCE when given the choice is that ISNULL tends to produce query plans that are more efficient than COALESCE's. Examine the query plans for the two queries given below to see the difference:

-- These two yield different execution plans. 
select a.au_id,
isnull( (select price from titles where title_id = ta.title_id), 0 )
from authors a
join titleauthor ta on a.au_id = ta.au_id
select a.au_id,
coalesce( (select price from titles where title_id = ta.title_id), 0 )
from authors a
join titleauthor ta on a.au_id = ta.au_id

The first query uses one less nested loop than the second, resulting in a lower overall cost. I wouldn't recommend writing queries that nest subqueries within functions anyway, but the example was only intended to show the difference in generated execution plans, not to recommend a certain T-SQL coding style.

The other bit of trivia most people don't know about ISNULL and COALESCE is that the return data type for ISNULL is guaranteed to be the same as the data type of the first parameter. However, the return data type of COALESCE is determined by data type precedence rules (see the Books Online topic "Data Type Precedence"). Therefore, the following queries will produce different output:

declare @Example char(2) 
set @Example = null
select isnull( @Example, 'abcde' ), coalesce( @Example, 'abcde' )
The first expression using ISNULL will return 'ab', which is the declared datatype of the first parameter, a char(2). The second expression using COALESCE will return the highest precedence data type, which is the longer string 'abcde.'

Take-home lessons:
  1. When you only need to coalesce two arguments, use ISNULL instead.
  2. When using COALESCE, use explicit casting to ensure you get a consistent return data type and also to make the meaning of the code clear to those who are less knowledgeable about the quirks of ISNULL and COALESCE than you are now. ;)
posted on April 5, 2006  #    by Adam Anderson  Comments [0] Trackback
 Friday, March 31, 2006

In .NET 1.1 we always had a problem using the built in Mail class in the System.Net namespace whenever the mail server was on a different server than the authenticating web server because it lacked the authentication feature to the SMTP that allows for this to be transfered correctly.  So we always ended up using a 3rd party component like ASPNETEMAIL which worked pretty well for us.
With the release of .NET 2.0 obviously Microsoft worked on that feature and added the authentication feature to the Mail class. 
This is simple code to show how easy now it is to make this work in .NET 2.0

1 System.Net.Mail.MailMessage Email = new System.Net.Mail.MailMessage ("spamMe@falafel.com", "SpamThis@falafel.com");
2 Email.Subject = "test subject";
3 Email.Body = "this is a test";
4 System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient();
5 //This object stores the authentication values
6 System.Net.NetworkCredential basicAuthenticationInfo = new System.Net.NetworkCredential ("username", "password");
7 mailClient.Host = "mail.falafel.com";
8 mailClient.UseDefaultCredentials = false;
9 mailClient.Credentials = basicAuthenticationInfo;
10 mailClient.Send(Email);
posted on March 31, 2006  #    by Lino Tadros  Comments [0] Trackback

When paging just won't cut it, scrollbars come in handy. Fortunately, it is quite easy to add scrolling support to just about anything. All you need to do is wrap any of your controls in an HTML DIV tag.

The key to the code below is to set the DIV style to "OVERFLOW: auto;" and specify a size. When overflow is set to auto, scrollbars will automatically appear if  the control size exceeds the DIV's dimensions. The code below binds a datagird to the Order table in the Northwind database. This would normally produces a pretty large datagrid, but thanks to our DIV, we will only see a subsection of the data.

<DIV style="OVERFLOW: auto; WIDTH: 550px; HEIGHT: 200px">
<asp:datagrid id=DataGrid1 runat="server" DataSource="<%# dataView1 %>"
AutoGenerateColumns="False" ShowHeader="False">
<Columns>
<asp:BoundColumn DataField="OrderID"></asp:BoundColumn>
<asp:BoundColumn DataField="ShippedDate"></asp:BoundColumn>
<asp:BoundColumn DataField="ShipName"></asp:BoundColumn>
<asp:BoundColumn DataField="ShipCity"></asp:BoundColumn>
</Columns>
</asp:datagrid>
</DIV>
posted on March 31, 2006  #    by Mike Dugan  Comments [0] Trackback
 Wednesday, March 29, 2006

Given an array of bytes containing the file data, a MIME type, and a file name:

public void DownloadBytes( byte[] bytes, string mimeType, string fileName )
{
  Response.ContentType = mimeType;
  Response.AppendHeader( "Content-Disposition", "attachment;filename=" + fileName );
  Response.BinaryWrite( bytes );
  Response.Flush();
  Response.End();
}

posted on March 29, 2006  #    by Adam Anderson  Comments [0] Trackback
 Thursday, March 23, 2006

The .NET Framework offers two methods for rounding: Decimal.Round() and Math.Round(). However, both methods implement a type of rounding known as "banker's rounding," which rounds .5 to the nearest even number. This is a different implementation from the "standard" arithmetic rounding most people are familiar with, where .5 rounds "up." Even the definition of "up" can vary, depending on whether the rounding is symmetric or asymmetric. Symmetric rounding rounds in the same direction relative to 0 (either towards or away). Asymmetric rounding always rounds in the same absolute direction (towards positive infinity or negative infinity).

Banker's rounding has its benefits, but it can cause incompatibility with other systems that implement different rounding schemes. For example, Math.Round( 8.5m ) will round to 8 in .NET, but round( 8.5, 2 ) will round to 9 in T-SQL. Inside is source code that implements arithmetic symmetric rounding in .NET, the type of rounding that T-SQL uses.

See How To Implement Custom Rounding Procedures for additional information

/// <summary>
/// Implements alternate rounding methods, in contrast to Decimal.Round()
/// and Math.Round(), which implement banker's rounding (5 rounds to even).
/// See http://support.microsoft.com/?kbid=196652 for other methods.
/// </summary>
public static class Round
{
  #region Methods

  #region ArithSym
  /// <summary>
  /// Rounds using arithmetic (5 rounds up) symmetrical (up is away from zero) rounding
  /// </summary>
  /// <param name="d">A Decimal number to be rounded.</param>
  /// <param name="decimals">The number of significant fractional digits (precision) in the return value.</param>
  /// <returns>The number nearest d with precision equal to decimals. If d is halfway between two numbers, then the nearest whole number away from zero is returned.</returns>
  public static decimal ArithSym( decimal d, int decimals )
  {
    decimal factor = Convert.ToDecimal( Math.Pow( 10, decimals ) );
    int sign = Math.Sign( d );
    return Decimal.Truncate( d * factor + 0.5m * sign ) / factor;
  }
  #endregion ArithSym

  #endregion Methods
}

posted on March 23, 2006  #    by Adam Anderson  Comments [0] Trackback
 Friday, March 17, 2006

I'm still playing around with that MakeRegion macro that Philip first posted. Today I added a regular expression to parse the first line of code and extract only the member name instead of the entire line.

For instructions on how to install, see The Blog That Started It All.

Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Imports System.Text.RegularExpressions

Public Module Regions

  Sub MakeRegion()
    Regions.MakeRegion()
  End Sub

  Public Class Regions
    ' MakeRegion inserts #region and #endregion tags
    ' around selected text in the VS editor.
    Shared Sub MakeRegion()
      Dim rName As String = ""
      Dim pad As String = ""
      Dim junk As String
      Dim count, i As Integer
      Dim startpoint, endpoint, tmppoint As EditPoint

      With DTE.ActiveDocument.Selection
        startpoint = .TopPoint.CreateEditPoint()
        endpoint = .BottomPoint.CreateEditPoint
      End With

      If startpoint.EqualTo(endpoint) Then
        Exit Sub
      End If

      'ELR: ADDED THIS, to move the startpoint to the start of the line()
      'so that the Pad function works correctly
      If Not startpoint.AtStartOfLine Then
        startpoint.StartOfLine()
      End If

      Dim DefaultResponse = GetDesc(DTE.ActiveDocument.Selection.TopPoint.CreateEditPoint())
      Dim re As Regex = New Regex("\s(\w+)\s*(?:\(|\:|$)")
      DefaultResponse = re.Match(DefaultResponse).Groups(1).Value

      'IV 2004-12-13: rName = InputBox("Region Name:")
      rName = InputBox("Type the name you want to give to the region, which will appear in the Visual Studio Code Editor.", "Make Region", _
      DefaultResponse)

      rName = rName.Trim()

      If rName.Length = 0 Then
        Exit Sub
      End If

      DTE.UndoContext.Open("Insert A Region")
      Try
        junk = startpoint.GetText(startpoint.LineLength)

        pad = String.Empty
        For count = 0 To junk.Length - 1
          If junk.Substring(count, 1).Equals(" ") _
          Or junk.Substring(count, 1).Equals(vbTab) Then
            pad += junk.Substring(count, 1)
          Else
            Exit For
          End If
        Next

        'ELR: ADDED Test for Languages
        If DTE.ActiveDocument.Language = "CSharp" Then
          ' C Sharp Code
          startpoint.Insert(String.Format("{0}#region {1}{2}", _
           pad, rName, vbCrLf))
          If endpoint.LineLength = 0 Then
            endpoint.Insert(String.Format("{0}#endregion {1}{2}", _
             pad, rName, vbCrLf))
          Else
            endpoint.Insert(String.Format("{0}#endregion {1}", _
             vbCrLf & pad, rName))
          End If
        Else
          ' VB Code
          startpoint.Insert(String.Format("{0}#Region {1}{2}", _
           pad, rName, vbCrLf))
          If endpoint.LineLength = 0 Then
            endpoint.Insert(String.Format("{0}#End Region '{1}{2}", _
             pad, rName, vbCrLf))
          Else
            endpoint.Insert(String.Format("{0}#End Region '{1}{2}", _
             vbCrLf & pad, rName, vbCrLf))
          End If
        End If
      Finally
        DTE.UndoContext.Close()
      End Try
    End Sub

    ' IV: Get the description from the 1st line of code in the region
    ' i.e. ignore c# comment tags (///) or take 1st line of the comments (//)
    ' Requires adjustments for VB and other langs
    Private Shared Function GetDesc(ByVal startpoint As EditPoint) As String
      Dim line As String = ""
      Dim tmppoint As EditPoint

      line = startpoint.GetText(startpoint.LineLength)
      If (line.Length > 0) Then
        line = line.TrimStart(" ", vbTab)
        If DTE.ActiveDocument.Language = "CSharp" Then
          If (line.StartsWith("///")) Or (line.StartsWith("[")) Then
            tmppoint = startpoint
            tmppoint.LineDown()
            line = GetDesc(tmppoint)
          ElseIf (line.StartsWith("//")) Then
            line = line.TrimStart("//", " ")
          End If
          line = line.Replace("{", String.Empty)
        End If
        line = line.TrimEnd(" ", vbTab)
      End If
      Return line
    End Function
  End Class

End Module

posted on March 17, 2006  #    by Adam Anderson  Comments [0] Trackback
 Thursday, March 16, 2006

Here's a little code snippet that will search a collection of Controls for the first control of a specified type.

private object FindControlByType( Control root, Type t )
{
  if ( root != null && root.GetType().Equals( t ) )
    return root;
  foreach( Control c in root.Controls )
  {
    object node = FindControlByType( c, t );
    if ( node != null && node.GetType().Equals( t ) )
      return node;
  }
  return null;
}

Example: the following example returns the first instance of an HtmlForm in a Page's Control collection:

HtmlForm form = (HtmlForm) FindControlByType( Page, typeof( HtmlForm ) );
posted on March 16, 2006  #    by Adam Anderson  Comments [0] Trackback

Here's a mysterious bit of code that doesn't look like it ought to work, but yet it does

select top 1 *
from table
order by newid()

posted on March 16, 2006  #    by Adam Anderson  Comments [1] Trackback