简体   繁体   中英

Unable to compare datetime variables in stored procedure sql server

I am trying to compare two datetime variables in a stored procedure sql server. In the below code snippet @createdDate is taken as user input and then comparing with a column of type datetime. I am unable to check the ''='' property

set @sqlquery = 'Select
            v.*,
            vsc.vidhanSabhaConstituencyName, where 1=1 '

set @sqlquery = @sqlquery +'AND v.createdBy ='''+cast(@createdBy as nvarchar(100))+''''

if(@VoterIdNumber is not null)
set @sqlquery = @sqlquery+'AND v.voterIDNumber= '''+@VoterIdNumber+''''

if(@createdDate is not null)
set @sqlquery = @sqlquery+'AND v.dataIsCreated = '''+cast(@createdDate as varchar(100))+''''
else
set @sqlquery = @sqlquery+'AND v.dataIsCreated= '''+cast(getdate() as varchar(100))+'''' 

Execute sp_Executesql @sqlquery

I've tried casting and converting the @createdDate variable without success. It works with other operators like >= or <= but not with = .

Help is appreciated

我只是给你一个例子,这里的SMSDATE是datetime,它为我提供了输出。尝试在您的过程中实现相同的逻辑

SELECT COUNT(*) FROM tbl_1 WHERE  CONVERT(varchar, SMSDATE,110)  = CONVERT(varchar, GETDATE(),110) 

First, you shouldn't use cast on a datetime . Use convert instead so you can specify an appropriate format for the result. The output of cast is going to depend on your region settings. For instance, when I run select cast(getdate() as varchar(100)); on my instance of SQL Server, I get the following:

Mar 15 2018  9:37AM

The precision of this value is obviously far more limited than that of a datetime : any two datetime values that happen to occur within the same minute will be converted to the same string. So if I try to use = to compare this value to values stored in a datetime field of a table, I'll find that the comparison will fail if the stored value has a nonzero seconds or milliseconds component.

If you must convert a datetime to a string, use convert with the style parameter that is most appropriate for how you're going to use it. For instance, if I run select convert(varchar(100), getdate(), 126); , I get:

2018-03-15T09:43:42.240

This is a much better choice of format for a date/time literal because it doesn't discard any data from the original value (like how my first example lost its seconds and milliseconds components) and is usable regardless of your region settings.

All that said, Marc Gravell had a very important comment on your question: you should be passing in a string of parameters rather than trying to concatenate everything. This will work even if the number of parameters that you actually want to include in your predicate is variable. For instance, consider the following example:

create table dbo.Test (A int, B datetime);
insert dbo.Test values (1, getdate());
go

declare @A int;
declare @B datetime;

declare @sql nvarchar(max) = 'select * from dbo.Test where 1=1';

if @A is not null
    set @sql = @sql + ' and A = @A';
if @B is not null
    set @sql = @sql + ' and B = @B';

print @sql;
exec sp_executesql @sql, N'@A int, @B datetime', @A = @A, @B = @B;

If I run this query as written, with @A and @B both left at null, then the value of @sql will simply be:

select * from dbo.Test where 1=1

If I set @A to 1, then I get:

select * from dbo.Test where 1=1 and A = @A

If I also set @B to a non-null value, then I get:

select * from dbo.Test where 1=1 and A = @A and B = @B

This is much easier to understand and maintain, and it's much safer as well. All the string concatenation you're doing in your original query is just begging for a SQL injection attack. You can either read up on this topic at this link , or simply consider what will happen to your query if I do something like:

set @createdBy = 'Admin''; drop table dbo.v; --';

This should be enough to go on, but feel free to ask if you have any questions.

You can try like this

declare @date datetime
set @date = '2018-03-13'
select * from user_tbl where cast(createddate as date) = cast(@date as date)
here, @date should be your sp date parameter

I have modified my stored procedure as suggested by Marc and Aaron. Below is my code snippet .

set @sqlquery = N'Select
            v.*,
            vsc.vidhanSabhaConstituencyName,
            lsc.lokSabhaConstituencyName,
            wc.wardName.....''

SET @sqlquery = @sqlquery + N' AND v.createdBy = @createdBy';
        If @VoterIdNumber Is Not Null SET @sqlquery = @sqlquery + N' AND v.voterIDNumber = @VoterIDNumber';

        If @createdDate Is Null SET @createdDate = null
                SET @sqlquery = @sqlquery + N' AND CONVERT(date, v.dataIsCreated) = @createdDate';

                EXEC sp_executesql
    @sqlquery,
    N'@createdBy varchar(50), @VoterIDNumber varchar(50), @createdDate date',

                @createdBy = @createdBy,
                @VoterIDNumber = @VoterIdNumber,
                @createdDate = @createdDate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM