简体   繁体   中英

Conversion failed when converting date and/or time from character string

I am trying to query the database where date is between today and yesterday but am getting error saying Conversion failed when converting date and/or time from character string.

My query is below with my parameters today and yesterday

string today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).ToString("yyyy-MM-dd");
        string yesterday= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day-1).ToString("yyyy-MM-dd");


        string errorsPerHourQuery = "WITH data_CTE(ErrorDay)" +
                    "AS(" +
                    "SELECT DATEPART(hh, Date) AS ErrorDay FROM cloud.ErrorLog " +
                    "WHERE Date BETWEEN '@yesterday' AND '@today' " +
                    "AND  CAST(Message AS varchar(200)) ='@message'"+
                    ")" +
                    "SELECT ErrorDay, COUNT(*) AS count FROM data_CTE GROUP BY ErrorDay ORDER BY ErrorDay";

conn.Open();
            cmd.Parameters.AddWithValue("@message", message);
            cmd.Parameters.AddWithValue("@yesterday", yesterday);
            cmd.Parameters.AddWithValue("@today", today);
            cmd.CommandType = CommandType.Text;

First off, you're calculating your today and yesterday wrong. Here's the correct way:

var today = DateTime.Today;
var yesterday = today.AddDays(-1);

And regaring query: remove ticks ( ' ) from around your named parameters so that your query reads ...BETWEEN @yesterday and @today... and you'll be all set.

You must remove simple cote ' from parmeters in query :

..BETWEEN @yesterday AND @today

You don't need to create today and yesterday with specific format, you can simply get variable like :

var today = DateTime.Today;
var yesterday = DateTime.Today.AddDays(-1);

and use Parameter with SqlDbType.DateTime and then pass the DateTime directly to the parameter (do not need to convert).

cmd.Parameters.Add("@yesterday", SqlDbType.DateTime).Value = yesterday
cmd.Parameters.Add("@today", SqlDbType.DateTime).Value = today

Problem is that you are quoting your command parameters which is getting considered as string literal instead of parameter as seen below.

WHERE Date BETWEEN '@yesterday' AND '@today'

You should change it to

WHERE [Date] BETWEEN @yesterday AND @today

There are lots of good points in the other answers especially. @Abdellah does a good job of teaching the datetime datatype and the appropriate value, but your SQL query itself needs work and may be why you are not getting what you want. Because just like the @yesterday and @today you need to remove the ''(ticks) from @message . Then you can do your query in 1 step you don't need the cte. Plus if you aren't going to pass any dates other than yesterday or today there is no need for parameters use SQL's built in functions.

So remove all of the ticks around all of your parameters (@yest...)

Here is a SQL query that should work for you:

SELECT
    ErrorHour = DATEPART(HH,[Date])
    ,[Count] = COUNT(*)
FROM
    cloud.ErrorLog
WHERE
    --use this line from midnight yesterday to midnight today
    CAST([Date] AS DATE) BETWEEN CAST(GETDATE() - 1) AND CAST(GETDATE())

    --what is the datatype for message does it really need to be cast?
    AND CAST([Message] AS VARCHAR(200)) = @Message
GROUP BY
    DATEPART(HH,[Date])
ORDER BY
    ErrorHour

Note I put ErrorHour you are welcome to change to ErrorDay , but you are counting errors per hours not days, to change what you are counting simply change your DATEPART() to be the time component you want, eg minutes, etc..

Next Do you really need to cast Message field?

On the dates. Are you wanting everything today and yesterday or really just yesterday? If just yesterday swap this line into the query for the other date line:

--if you really just want yesterday midnight to 11:59:59 PM the it should be CAST([Date] AS DATE) = CAST(GETDATE()-1 AS DATE)

Next if you really really want to pass yesterday and today as parameters and you want all of yesterday and all of today do the following and update your parameter definitions in your code as the other posts suggest.

--use this line from midnight yesterday to midnight today CAST([Date] AS DATE) BETWEEN CAST(@yesterday AS DATE) AND CAST(@Today AS DATE)

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