Philip Hendry's Blog

September 29, 2009

Setting Opera as the default browser on a Windows Mobile

Filed under: Windows Mobile — philiphendry @ 11:47 am

I own an HTC Touch HD as was getting a bit annoyed at Internet Explorer being the default browser when selecting links from emails. However, Opera Mobile has a ‘hidden’ configuration screen and can be used to set it as the default :

  1. Run Opera
  2. Enter ‘opera:config’ in the address bar
  3. Find the ‘Install’ section
  4. Select ‘Browser First Time Launch’ checkbox
  5. Press ‘Save’
  6. Soft reset

Generating a list of numbers in T-SQL

Filed under: SQL Server, T-SQL, Tip — philiphendry @ 8:33 am

I wanted to create a list of numbers so I could cross join them to another set of data to generate some test data quickly. There are ways to generate numbers using a CTE (Common Table Expression) or if you’re in a real hurry you can make us of a fairly undocumented table called master..spt_values. Seeing as this table isn’t well documented don’t go using it for production code since it might change but for quick one-off tasks it seems fine.

The following SQL creates a list of numbers from 0 to 2047 :

select [number]
from master..spt_values
where type = 'P'

September 21, 2009

ASP.NET Page Life Cycle Diagram

Filed under: ASP.NET, Tip — philiphendry @ 7:42 pm

I saw this months ago and wondered where it had gone so when I came across it by chance whilst googling I thought I would save myself a link to it. Many thanks to Raymond Lewallen who credits Leon Andrianarivony!

image

Sproc Compile Locks

Filed under: MSDN Article Summary, SQL Server, Tip — philiphendry @ 7:28 pm

I came across an article on Microsofts support site which has raised a point which I’d never considered before. It basically says that if the user that executes a stored procedure is not the owner of the procedure then locks are acquired during the process to find a cached plan that may lead to blocking. It also states this could be avoided by fully qualifying the sproc name (e.g. dbo.mysproc) when calling it to avoid the extra lookups. This has been a problem for me in the past since the projects I’ve worked on had been setup with an account running as dbowner, however, if I was setting up a database from scratch I’d set up a specific user(s) for accessing the database and give it just the permissions it requires (sproc execute permissions for example.) I think, therefore, this would fall into these problem. However, I would also make use of the schema prefix (e.g. Sales.Order table) rather than leaving it as dbo and therefore avoid this problem altogether.

September 18, 2009

Generic Sorting Routine for ASP.NET GridView

Filed under: ASP.NET, Dev Problem, LINQ — philiphendry @ 7:41 pm

I noticed a lot of code in the current project I’m working on which looked something like this :

switch (sortExpression)
{
    case "Name":
        items.OrderBy(i => i.Name);
        break;
    case "Date":
        items.OrderBy(i => i.Date);
        break;
    case "Cost":
        items.OrderBy(i => i.Cost);
        break;
}

This was then repeated all over again for descending orders!! I’ve now replaced it with something like this :

private void Populate(string sortExpression)
{
   var items = GetData();
   gvList.DataSource = CreateValueList(items).OrderByExpression(new OrderByExpression(sortExpression));
   gvList.DataBind();
}

The sort expression is handled by the GridView code such that AllowSorting is turned on and the OnSorting event is wired up to a method :

<asp:GridView ID="gvList" runat="server" AllowSorting="True" OnSorting="gvList_Sorting" DataKeyNames="ID">
   <Columns>
       <asp:TemplateField HeaderText="Name" SortExpression="Name">
           <ItemTemplate>
               <asp:Label Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' runat="server" ID="lblName" />
           </ItemTemplate>
       </asp:TemplateField>
   </Columns>
</asp:GridView>

The code-behind deals with the sorting events and calls populate :

protected void gvList_Sorting(object sender, GridViewSortEventArgs e)
{
   Populate(e.SortExpression + " " + GetSortDirection(e.SortExpression));
}

private string GetSortDirection(string column)
{

   // By default, set the sort direction to ascending.
   string sortDirection = "ASC";

   // Retrieve the last column that was sorted.
   string sortExpression = ViewState["SortExpression"] as string;

   if (sortExpression != null)
   {
       // Check if the same column is being sorted.
       // Otherwise, the default value can be returned.
       if (sortExpression == column)
       {
           string lastDirection = ViewState["SortDirection"] as string;
           if ((lastDirection != null) && (lastDirection == "ASC"))
           {
               sortDirection = "DESC";
           }
       }
   }

   // Save new values in ViewState.
   ViewState["SortDirection"] = sortDirection;
   ViewState["SortExpression"] = column;

   return sortDirection;
}

What this all boils down to is the OrderByExpression() extension method called in the Populate() method above:

   public static IEnumerable<TSource> OrderByExpression<TSource>(this IEnumerable<TSource> data, OrderByExpression expression)
   {
       string sortOrderMethod = (expression.SortOrder == SortOrderEnum.Ascending) ? "OrderBy" : "OrderByDescending";

       // data.OrderBy(o => o.propertyname);   
       var dataAsQueryable = data.AsQueryable<TSource>();
       ParameterExpression lambdaParameter = Expression.Parameter(typeof(TSource), "o");
       MemberExpression member = Expression.PropertyOrField(lambdaParameter, expression.SortProperties[0]);
       LambdaExpression lambda = Expression.Lambda(member, lambdaParameter);
       Type[] argumentTypes = { dataAsQueryable.ElementType, lambda.Body.Type };
       MethodCallExpression orderBy = Expression.Call(typeof(Queryable), sortOrderMethod, argumentTypes, dataAsQueryable.Expression, lambda);
       return dataAsQueryable.Provider.CreateQuery<TSource>(orderBy);
   }

I have to say thanks to Joseph Albahari and Ben Albahari of LinqPad fame since I found this solution to my problems (after getting within so close through my own efforts whilst our internet connection was down in the office!!) in the samples that came with LinqPad.

The code above creates a dynamic Linq expression then executes it through the queryables provider – although this only occurs once the whole linq expression is enumerated.

The last few modifications I need to make require the order by to cope with multiple properties (The OrderByExpression.SortProperties class already supports multiple properties but I’m only taking the first at the moment) and I need to ensure that the query always deferred since composable against a database – this is important since I’ve yet to consider paging in the GridView and I want to make sure that specifiying .Skip(n).Take(m) can be applied after the ordering but the Linq expression be composed as SQL and executed against the database in one go otherwise I’ll be returning all the rows to the application layer before extracting just the required rows for the current page.

September 15, 2009

Importing from Excel into SQL Server

Filed under: SQL Server, T-SQL — philiphendry @ 10:54 am

I was going through a mountain of pain trying to get an import working from an Excel spreadsheet working into SQL Server 2005 but I finally managed it and here’s how…

Here’s the SQL I’m using (slightly abridged!) :

set transaction isolation level read committed

declare @sql nvarchar(1024)
set @sql = 'select * into ##Temp from opendatasource(''Microsoft.Jet.OLEDB.4.0'', ''Extended Properties=Excel 8.0;Data Source=' + @ExcelFileToImport + ''')...' + @ExcelWorkSheet
exec sp_executesql @sql

Points to note :

  • I’m using dynamic sql because the opendatasource() doesn’t like being passed variables… so be sure to validate the contents of @ExcelFileToImport and @ExcelWorkSheet.
  • Because I was forced to use dynamic sql I had to use a global temporary table. I wanted to load the data into a temporary table so that the columns were generated on-the-fly and I could check the correct columns were supplied by examining tempdb.sys.columns. It therefore had to be a global temporary because a standard one would have been thrown away after sp_executesql() had finished! For my situation the global temporary table is ok… but you’ll have to consider your own situation and whether concurrency allows.
  • I kept getting the error below on the subsequent re-tries of uploading but worked around this by adding ‘set transaction isolation level read committed’ in the sproc.

    The requested operation could not be performed because OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)" does not support the required transaction interface.

I was having trouble executing within a transaction but with the changes made above the sql could be called with the following :

using (TransactionScope scope = new TransactionScope())
{
    UploadExcelIntoDatabase(importTicket, importFilename);
    scope.Complete();
}

September 11, 2009

Conditional Aggregate Totals in SQL

Filed under: SQL Server, T-SQL, Tip — philiphendry @ 8:03 am

I’ve been working on a SQL Server Reporting Services report which had to display several counts on each row. Each row represented a project and each project could have several tasks that were either ordinary tasks or milestones and could also be escalated. The report need to show something like this :

Project Name Milestone Counts Task Count Escalated Task Count
1st Week 2nd Week 3rd Week >=4th Week Total 1st Week 2nd Week 3rd Week >=4th Week Total

As you can see a task initially has to break down into two major colours of milestone and ordinary task counts but then is broken down into counts in the 1st, 2nd, 3rd and greater than 4th week totals including the total itself.

Initially this seemed tricky when thinking in terms of using count() but there’s an incredibly simple technique that solves this but which isn’t immediately obvious. The Sum() aggregate function can contain an expression and in this example that expression could compare the task date against late week dates and return either a 1 or 0 :

select ProjectName,
   sum(case when IsMilestone = 1
      and TaskDate < @LateDate
      and Taskdate >@OneWeekLateDate
      then 1 else 0 end) as Week1LateMilestoneCount
from Project
group by ProjectName

I’ve only included one example there but I think it’s enough to get the idea.

September 7, 2009

Return values from stored procedures using the Enterprise Library Data Access block

Filed under: Code, Enterprise Library — philiphendry @ 3:26 pm

I’m not sure why I had so much trouble trying to do this… but because it did I think it’s worth a blog. Basically I was trying to return an int value from a stored procedure but couldn’t quite work out the syntax and was initially distracted by trying to use AddOutParameter() . However, the key was to use AddParameter() specifying the direction as ReturnValue :

db.AddParameter(cmd, "@return_value", DbType.Int32, ParameterDirection.ReturnValue, null, DataRowVersion.Default, null);

Then simply access the named parameter :

Convert.ToInt32(db.GetParameterValue(cmd, "@return_value"))

September 2, 2009

Selecting a result set from a stored procedure in SQL Server

Filed under: SQL Server, T-SQL, Tip — philiphendry @ 10:55 am

Selecting data from a stored procedure in SQL Server is already a documented feature and here’s an example:

insert into #systables exec sp_executesql N'select * from Northwind.sys.tables'

…problem is this example doesn’t run without first creating the temp table and therefore knowing all the column definitions. When I’m running quick queries this isn’t exactly convenient. I’ve seen blogs posts using a linked server but there’s another way :

select * into #systables
from openrowset(
   'sqlncli',
   'server=.;trusted_connection=Yes',
   'sp_executesql N''select * from Northwind.sys.tables'''
)

I wouldn’t necessarily use this as a day-to-day process on a production environment but for administration or scripting installations I think it fits the bill.

August 28, 2009

Lazy Loading Entities Referenced By The Returned Entities from a Stored Procedure in Entity Framework V1

Filed under: Code, Entity Framework — philiphendry @ 1:52 pm

Phew, that’s the title out of the way!!

I had a simple plan – run some complex and optimised SQL and return a graph of entities back to the app using Entity Framework. First problem is it doesn’t support returning anything but a single entity from the stored procedure so that’s eager loading done for! Second problem is the entity has to exist in the model so creating a POCO is out of the question and I’m not so sure about creating arbitrary data transfer objects in the model either (EF V2 should help with this.)

So I resorted to running the sproc then lazy loading the child objects I need. What I needed to do though was traverse a couple of references and test a field to limit the returned rows. And here’s what I ended up with after much poking around :

image

There are two straight-forward lazy loads using .Load() but I’m only attaching entities for Child3 based on the results of the ‘inner query’ which uses .CreateSourceQuery() to create a queryable.

Older Posts »

Blog at WordPress.com.