views:

106

answers:

4

I want to rewrite this query so that if @UserName gets passed in a null value then it leaves the Client_User out of the search criteria. I only want it to search by name if the user enters a name in the username textbox on the webform. I'm not sure how to do this.

select * from weblogs.dbo.vwlogs 
where Log_time between @BeginDate and @EndDAte 
and  client_user=@UserName
A: 
select * 
from weblogs.dbo.vwlogs 
where Log_time between @BeginDate and @EndDAte 
  and (client_user=@UserName or @UserName IS null)
Carlton Jenke
@UserName IS NULL rather than @UserName = NULL
Joel Coehoorn
Unless "SET ANSI_NULLS = OFF" - which is the Work of the Devil IMHO!
Kristen
+5  A: 

select * from weblogs.dbo.vwlogs where Log_time between @BeginDate and @EndDAte and (@UserName IS NULL OR client_user=@UserName)

Kristen
A: 

The solution from Kristen will work, but if you need performance, don't do it because the plan will be cached only for the first condition.

So, if your procedure gets called with the NULL parameter first, that query will be cached.

If you need higher performance, use an IF statement and create two distinct queries.

In more complicated queries event sp_execsql will be faster.

muerte
I agree, but if the code is in a Stored Procedure then parameter Sniffing may assist ... and if its just dynamic SQL then all bets are off anyway with regard to caching - or, as you say, better still use sp_ExecuteSQL with explicitly generated WHERE clause so that each variant is separately cached
Kristen
Yes, in any case, your answer is right, i've upmoded it. My answer is just additional info...
muerte
A: 

The best solution is to utilize sp_execute_sql. For example:

--BEGIN SQL
declare @sql nvarchar(4000)

set @sql = 
'select * from weblogs.dbo.vwlogs 
where Log_time between @BeginDate and @EndDate'
+ case when @UserName is null then '' else 'and client_user = @UserName' end

sp_execute_sql
@sql
, @params = '@UserName varchar(50)'
, @UserName = @UserName
--END SQL

As muerte mentioned, this will have a performance benefit. According to BOL:

sp_executesql can be used instead of stored procedures to execute a Transact-SQL statement a number of times when the change in parameter values to the statement is the only variation. Because the Transact-SQL statement itself remains constant and only the parameter values change, the Microsoft® SQL Server™ query optimizer is likely to reuse the execution plan it generates for the first execution.

Cadaeic
Well, this is probably overkill for 2 arguments. Useful when you have more, though.
Marc Gravell
Like so: http://stackoverflow.com/questions/532468/ignoring-a-null-parameter-in-t-sql
Marc Gravell
Not sure overkill for 2 args. The query plan cached for the "@UserName IS NULL OR COL=@UserName" SProc will be based on its first use. That may wreck the performance of the alternative @UserName present/absent scenario.sp_ExecuteSQL direct from APP may be best - but still needs SELECT permission
Kristen