Tag Archives: Data

@@ROWCOUNT is affected by IF statement

Let’s say you’re writing T-SQL code and need to make sure that your query returns one and only row. If no records returned – an error message needs to be shown. If more than one record is returned – another error message needs to be show. The code goes something like this:

-- ... query runs here and returns row

IF @@ROWCOUNT = 0 RAISERROR('No records found', 18, 1)
ELSE IF @@ROWCOUNT > 0 RAISERROR('More than one record found', 18, 1)

-- ... continue when exactly one row is returned

Now if your query returns 3 records you’d expect it to trip the second IF statement and raise error with correct message. Unfortunately this doesn’t happen. The reason being – the first IF statement resets @@ROWCOUNT to 0. So, to avoid this we need to preserve the @@ROWCOUNT value in a local variable:

DECLARE @iRowCount int

-- ... query runs here and returns row

SET @iRowCount = @@ROWCOUNT

IF @iRowCount = 0 RAISERROR('No records found', 18, 1)
ELSE IF @iRowCount > 0 RAISERROR('More than one record found', 18, 1)

-- ... continue when exactly one row is returned

This way count of rows returned by the query is saved and is not affected by any following statements.

ASP.NET: Delete file from server after TransmitFile command

It’s a common scenario: user needs to download a file from the server by clicking link or a button in your ASPX page. The server-side code for this is pretty straightforward and looks something like this:

Sub DownloadFile(ByVal i_sServerPath As String, ByVal i_sDisplayName As String)
   Dim oFile As FileInfo = New FileInfo(i_sServerPath)

   With Response
      .Clear()
      .ClearHeaders()
      .AddHeader("Content-Length", oFile.Length.ToString())
      .ContentType = ReturnContentType(oFile.Extension.ToLower())
      .AddHeader("Content-Disposition", "attachment; filename=" & i_sDisplayName)
      .TransmitFile(oFile.FullName)
      .End()
   End With

End Sub

The code accepts 2 parameters: i_sServerPath – full path to the file on the server and i_sDisplayName – file name that will be displayed to the user in the “Save As” dialog. Code also populates response headers based on file information. I use this handy function to populate ContentType based on file extention:

Function ReturnContentType(ByVal i_sfileExtension As String) As String
   Select Case i_sfileExtension
      Case ".htm", ".html", ".log" : Return "text/HTML"
      Case ".txt" : Return "text/plain"
      Case ".doc" : Return "application/ms-word"
      Case ".tiff", ".tif" : Return "image/tiff"
      Case ".asf" : Return "video/x-ms-asf"
      Case ".avi" : Return "video/avi"
      Case ".zip" : Return "application/zip"
      Case ".xls", ".csv" : Return "application/vnd.ms-excel"
      Case ".gif" : Return "image/gif"
      Case ".jpg", "jpeg" : Return "image/jpeg"
      Case ".bmp" : Return "image/bmp"
      Case ".wav" : Return "audio/wav"
      Case ".mp3" : Return "audio/mpeg3"
      Case ".mpg", "mpeg" : Return "video/mpeg"
      Case ".rtf" : Return "application/rtf"
      Case ".asp" : Return "text/asp"
      Case ".pdf" : Return "application/pdf"
      Case ".fdf" : Return "application/vnd.fdf"
      Case ".ppt" : Return "application/mspowerpoint"
      Case ".dwg" : Return "image/vnd.dwg"
      Case ".msg" : Return "application/msoutlook"
      Case ".xml", ".sdxl" : Return "application/xml"
      Case ".xdp" : Return "application/vnd.adobe.xdp+xml"
      Case Else : Return "application/octet-stream"
   End Select
End Function

It’s all good, but what if you need to delete the file from the server immediately after user downloaded it? Continue reading →

TSQL: Filling missing date range

Let’s say you have a table with some dates and numeric values e.g.:

2011-08-19	16
2011-08-22	45
2011-08-24	62
2011-08-25	88
2011-08-27	17
2011-08-28	35
2011-09-01	10
2011-09-02	79
2011-09-03	70
2011-09-07	83

As you can see not all dates are in the sequential order, 24th comes after 22nd etc. But in many cases you need this data to be sequential, for example if this data feeds a chart you need to fill it with missing dates and 0 for a value. There is an easy way to achieve this. Continue reading →

SQL Server stored procedure runs slow from .NET code

This has probably been discussed a lot before, but just in case here it is again, possible solution for following scenario:

You’re calling SQL Server stored procedure from your .NET code and it runs extremely slow. When you run same SP with exactly the same parameters (as captured by SQL Server Profiler) directly in SQL Server Management Studio, it runs very fast. What gives?

Chances are – that SP was executed before and query plan was cached for the specific parameters. To avoid this add WITH RECOMPILE option to your CREATE PROCEDURE or ALTER PROCEDURE statement. This will force SQL Server to create a new query plan every time SP runs, perhaps adding slight overhead, but creating an optimized path that will cover that overhead tenfold.

String Aggregate in LINQ

In the past I described how to perform string aggregates in T-SQL. In this post I will show how strings can be concatenated in LINQ.

I am using ADO.NET data table as a source for the query, but LINQ being LINQ can pull data pretty much from anything so this example can easily be adjusted.

First things first, let’s create the source. As in T-SQL post I am using ol’ faithful Northwind database and getting data from the Employees table:

Dim oConn As New SqlConnection(sMyConnStr) : oConn.Open()
Dim oComm As New SqlCommand("SELECT Country, FirstName FROM Employees ORDER BY Country, FirstName", oConn)
Dim oAd As New SqlDataAdapter(oComm) : Dim oTable As New DataTable : oAd.Fill(oTable)

This will fill the datatable with employees’ first names and countries

Country FirstName
UK      Anne
UK      Michael
UK      Robert
UK      Steven
USA     Andrew
USA     Janet
USA     Laura
USA     Margaret
USA     Nancy

And now we want to group this by the country, combining first names into comma separated string. Continue reading →

Opening SpreadsheetML 2003 in Excel 2010

If you’re trying to open an Excel 2003 XML file (SpreadsheetML) in Excel 2010 and getting “The file is corrupt and cannot be opened” error, try opening that file in WordPad (it will open as text XML) and save it back. Now try opening it in Excel 2010 again. You will still get “The file you’re trying to open is in a different format than specified by the file extension” warning, but after that the file should open.

Cheat for “These columns don’t currently have unique values” error

Ordinary when you create a parent-child relationship between DataTables in a DataSet – there is a requirement that all values of the parent columns need to be unique. If they’re not – you will get an error: “These columns don’t currently have unique values“.

But there’re times when you need to make the relationship work even if those values are not unique. The solution is not to create constrain when creating the relationship. This can be done for example by passing FALSE as value for createConstrains parameter of Dataset.Relations.Add method:

oMyDataSet.Relations.Add("MyRel", _
oMyDataSet.Tables("TheParent").Columns("ParentColumn"), _
dtSet.Tables("TheChild").Columns("ChildColumn"), _
False)

TSQL: Remove duplicate records. Clean and Simple

It’s a common scenario, your table has several records with identical values and you need to leave only one, deleting the rest. Here is a generic TSQL query (SQL Server 2005 and above) that does just that in a few lines:

WITH DUP_TABLE AS
   (SELECT ROW_NUMBER()
    OVER (PARTITION BY FIELD1, FIELD2 ORDER BY FIELD1, FIELD2) As ROW_NO
    FROM ORIGINAL_TABLE)
DELETE FROM DUP_TABLE WHERE ROW_NO > 1

Here ORIGINAL_TABLE is your table with duplicates. FIELD1 and FIELD2 are columns with duplicates value (feel free to add or remove columns to suit your needs). Internal query assigns a row number to each duplicate record and DELETE statements that uses that CTE deletes all the rows except the one with Row Number = 1

SSRS Query execution failed … Expected parameter …

Consider following scenario: While developing for SQL Server Reporting Services you created a report in Business Intelligent Studio (or generated RDL file elsewhere and then added it to Studio’s project). Everything works fine, you’re able to preview report. And then you need to change Data Source (one example: you created a shared Data Source and now want your report to use it). After you do that any attempt to run the report results in error: Query execution failed … Expected parameter ….

The reason in this case – when you change the data source thru GUI – it resets query used by the report. It can change query type from StoredProcedure to Text and also remove all default query parameters (hence error above).

There’re 2 possible solutions here: First – instead of using GUI, manually change Data Source in the XML source of the report file (in Solution Explorer right mouse click on the report file and select “View Code”). You will have to change it in several places, so be careful. Second – re-create query with its default parameters after changing Data Source in GUI.

WebHierarchicalDataGrid: Manual Load on Demand when bound to DataSet

Even though I have my issues with Infragistics WebHierarchicalDataGrid control, it has some neat features and I found that with some tweaks you can make it work.

Case in point: Manual Load on Demand. If you have hierarchical data structure, it allows you to retrieve only root level data and then when user clicks “Expand” arrow – get additional data on as needed basis:

Manual Load on Demand in action

This is achieved by handling RowIslandsPopulating grid’s event in which you can run a DB query based on parent row data, then manually create a ContainerGrid object bind it to the data and add it to parent row RowIslands collection:

Protected Sub myGrid_RowIslandsPopulating(ByVal sender As Object, ByVal e As ContainerRowCancelEventArgs) Handles myGrid_.RowIslandsPopulating

     e.Cancel = True

     Dim oData as SomeDataType = GetData()
     Dim oChildGrid As New ContainerGrid()

     e.Row.RowIslands.Add(oChildGrid)

     oChildGrid.DataKeyFields = "SOME_ID"
     oChildGrid.Level = e.Row.Level + 1
     oChildGrid.DataSource = oData
     oChildGrid.DataBind()

End Sub

For this approach to work top-level rows need to display “Expand” arrows that user can click. Continue reading →