Reputation: 4883
I have the following dynamic SQL query that I am using to filter results for a data range. If my "createdFrom
" and "createdTo
" date are not null, I add a where clause to my select statement.
I have 2 questions:
How would you go about doing this? Is my logic correct?
I am currently getting an error message when I add the below code, why would I be getting this?:
Conversion failed when converting character string to smalldatetime data type.
Declare @createdFromDate SMALLDATETIME = NULL ,
@createdToDate SMALLDATETIME = NULL
IF @createdFromDate IS NOT NULL
BEGIN
SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '+@createdFromDate
END
IF @createdToDate IS NOT NULL
BEGIN
SELECT @sWhere = @sWhere + ' AND g.CreatedOn <'+@createdToDate
END
Upvotes: 0
Views: 125
Reputation: 6018
What's causing your issue is your trying to concatenate a smalldatetime
with, so string data-types like VARCHAR
. You can just cast your dates as VARCHAR
to get around that. CONCAT()
would be even better though. It is your best friend when concatenating values of different data-types. I HIGHLY recommend using it, sadly it only is support by SQL Server 2012+ and above and not many know it even exists.
Now for you specific problem, I don't think dynamic SQL is necessary. You should generally try to avoid using dynamic SQL since it's hard to debug and make changes later. Something like this would work just fine for you.
Declare @createdFromDate SMALLDATETIME = NULL,
@createdToDate SMALLDATETIME = NULL
SELECT *
FROM yourTable
WHERE (
date_column > @createdFromDate
OR @createdFromDate IS NULL
)
AND
(
date_column < @createdToDate
OR @createdToDate IS NULL
)
Upvotes: 2
Reputation: 9890
For your question
I am currently getting an error message when I add the below code, why would I be getting this?
The reason you are getting this error is when the query is executed your condition becomes
AND g.CreatedOn > 2015-05-07
Which is invalid, but instead your need
AND g.CreatedOn > '2015-05-07'
Hence your SQL should be
SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '''+@createdFromDate + ''''
For your question
How would you go about doing this? Is my logic correct?
You should use sp_executesql
and pass the variable in your dynamic SQL like this.
IF @createdFromDate IS NOT NULL
BEGIN
SELECT @sWhere = @sWhere + 'AND g.CreatedOn > @createdFromDate'
END
IF @createdToDate IS NOT NULL
BEGIN
SELECT @sWhere = @sWhere + ' AND g.CreatedOn < @createdToDate'
END
Instead of
EXEC(@SQL)
You would use
EXEC sp_executeSQL @SQL,N'@createdFromDate smalldatetime,@createdToDate smalldatetime',@createdFromDate,@createdToDate
Where @SQL
is constructed from your @Where
Note: You don't need dynamic SQL if this is the only reason for using it.
Upvotes: 2
Reputation: 1271231
The direct answer to your question is that date constants need to be enclosed in single quotes. Instead of this:
SELECT @sWhere = @sWhere + 'AND g.CreatedOn > '+@createdFromDate
Use:
SELECT @sWhere = @sWhere + 'AND g.CreatedOn > ''' + @createdFromDate + ''''
The correct answer to your question is that you should use sp_executesql
for executing dynamic SQL. This allows you to include parameters, so you can just say:
exec sp_executesql @sql,
N'@createdFromDate date',
@createdFromDate = @createdFromDate;
where @sql
is a string that looks like:
select . . .
. . .
where . . . and
g.CreatedOn = @createdFromDate;
Upvotes: 2