views:

114

answers:

6

I have a SQL query in my ASP.net web app that looks like this:

SELECT * FROM [Records] WHERE ([title] LIKE '%' + @title + '%')

@title, of course, is the value of a text box on the page.

My question is, why, when the text box is empty, does this return nothing? And how can I make it return everything, like logic tells me it ought to?

A: 

Is it possible the value of @title is holding null or a single space?

Dougman
A: 

I'm not quite sure, but maybe this happens when @title is NULL. Operations on NULL generally return NULL, so you'd be comparing to NULL.

John Saunders
+2  A: 
SELECT * FROM [Records] 
WHERE @title IS NULL OR LEN(@Title) = 0 OR ([title] LIKE '%' + @title + '%') 
Mitch Wheat
@John Saunders: If it's SQL Server, then you have to use `RTRIM(LTRIM(@Title))` - there's no TRIM() function in TSQL :(
OMG Ponies
@Mitch: maybe LEN(RTRIM(LTRIM(@Title)))? @OMG: did a "late man's edit".
John Saunders
OK, this works when I query the database manually, but for some reason it doesn't work with the web form... I guess that's a separate question.
iansinke
A: 

Use

SELECT * FROM [Records] WHERE (isnull(@title,'') = '' or [title] LIKE '%' + @title + '%') 

Or do a check for an empty title in the client code, pass NULL if so, and do a condition: "@title is null or...".

Seva Alekseyev
A: 

NULL plus anything is NULL so while you might expect to get '%%' you are actually getting NULL. Since nothing is LIKE NULL (things IS NULL instead) you get nothing. You might try something like WHERE [TITLE] LIKE ISNULL('%' + @title + '%', '%'); If the first argument to ISNULL is NULL, it returns the second arg.

Andrew
+1  A: 

The most sargable option, short of using dynamic SQL, is to use an IF statement and two queries:

IF LEN(@Title) > 0

  SELECT r.*
    FROM RECORDS r
   WHERE r.title LIKE '%'+ @Title +'%'

ELSE

  SELECT r.*
    FROM RECORDS r

The SQL Server 2005+ dynamic SQL version would resemble:

DECLARE @SQL NVARCHAR(4000)
   SET @SQL = 'SELECT r.*
                 FROM RECORDS r 
                WHERE 1 = 1' --will be optimized out, easier to add clauses

   SET @SQL = @SQL + CASE LEN(@Title)
                       WHEN 0 THEN ''
                       ELSE ' AND r.name LIKE ''%''+ @Title +''%'' '   
                     END

BEGIN

  EXEC sp_executesql @SQL, N'@Title VARCHAR(#)', @Title

END

Unlike EXEC, sp_executesql will cache the query plan. You can read more about it in the Blessing & Curse of Dynamic SQL.

OMG Ponies