Question

Anyone know why the following is not working:

[WebMethod()]
public double GetDayCount(string strMeetingDate, string strMeetingTime)
{
    string[] strStartDateParts = strMeetingDate.Split('-');

    // change DMY to YMD
    strMeetingDate = strStartDateParts[2] + '-' + strStartDateParts[1] + '-' + strStartDateParts[0];

    using (connection = new SqlConnection(ConfigurationManager.AppSettings["connString"]))
    {

        using (command = new SqlCommand("BusinessHours", connection))
        {

            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add("@meeting_day", SqlDbType.DateTime).Value = strMeetingDate;
            command.Parameters.Add("@meeting_time", SqlDbType.DateTime).Value = strMeetingTime;

            connection.Open();

            using (reader = command.ExecuteReader())
            {
                reader.Read();
                return (double)reader["hours"];
            }
        }
    }
}

No error messages are returned, instead the value returned is incorrect.


Here is a full stored procedure.

USE [INTRANET]
GO
/****** Object:  StoredProcedure [dbo].[BusinessHours]    Script Date: 06/24/2013 11:38:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[BusinessHours]

@meeting_day DATETIME,
@meeting_time DATETIME

AS

DECLARE @submit_day DATETIME;
DECLARE @submit_time DATETIME;

DECLARE @start_time_of_business_day DATETIME;
DECLARE @business_day_hours FLOAT;

DECLARE @num1 FLOAT
DECLARE @num2 FLOAT
DECLARE @num3 FLOAT

SET @submit_day = CONVERT(VARCHAR(10),GETDATE(),101);
SET @submit_time =  CONVERT(VARCHAR(8),GETDATE(),108);

SET @start_time_of_business_day = '09:00';
SET @business_day_hours = 8.5;

SET @num1 = ((DATEDIFF(dd, @submit_day, @meeting_day))
-(DATEDIFF(wk, @submit_day, @meeting_day) * 2)
-(CASE WHEN DATEPART(dw, @submit_day) = 1 THEN 1 ELSE 0 END)
-(CASE WHEN DATEPART(dw, @meeting_day) = 7 THEN 1 ELSE 0 END)
-(SELECT COUNT(*) FROM bank_holiday WHERE the_date BETWEEN @submit_day AND @meeting_day)) * @business_day_hours
SET @num2 = (select datediff(minute, @start_time_of_business_day, @submit_time)) / 60.0
SET @num3 = (select datediff(minute, @start_time_of_business_day, @meeting_time)) / 60.0

select @num1 - @num2 + @num3 as [hours]

If I run the stored procedure manually (as in executing it from within sql server management studio by clicking on the stored procedures name and selecting execute), I get 0.666667 (value will be different based on current date/time and the date/time entered into the stored procedure). But when I run the .asmx file, I get 994728.666667.

Anyone know why this is happening? Basically, the .666667 part is correct in both examples, but for some reason the .asmx file seems to add 994728 to the correct value.

Was it helpful?

Solution

You're passing a string as a DateTime parameter. The following should work:

[WebMethod()]
public double GetDayCount(string strMeetingDate, string strMeetingTime)
{
    string[] strStartDateParts = strMeetingDate.Split('-');
    // not sure what your expected time format is
    string[] srtStartTimeParts = strMeetingTime.Split('-');

    int year = Int32.Parse(strStartDateParts[2]);
    int month = Int32.Parse(strStartDateParts[1]);
    int day = Int32.Parse(strStartDateParts[0]);
    int hour = Int32.Parse(srtStartTimeParts[0]);
    int min = Int32.Parse(srtStartTimeParts[1]);
    int sec = Int32.Parse(srtStartTimeParts[2]);

    DateTime meetingDate = new DateTime(year, month, day, hour, min, sec);
     using (connection = new SqlConnection(ConfigurationManager.AppSettings["connString"]))
    {
         using (command = new SqlCommand("BusinessHours", connection))
        {
             command.CommandType = CommandType.StoredProcedure;
             command.Parameters.Add("@meeting_date", SqlDbType.DateTime).Value = meetingDate;
             connection.Open();
             using (reader = command.ExecuteReader())
            {
                reader.Read();
                return (double)reader["hours"];
            }
        }
    }
}

Then change your sproc to parse out the date and time from your argument:

ALTER PROCEDURE [dbo].[BusinessHours]

@meeting_date DATETIME

AS

DECLARE @meeting_day DATETIME
DECLARE @meeting_time DATETIME
DECLARE @submit_day DATETIME;
DECLARE @submit_time DATETIME;

DECLARE @start_time_of_business_day DATETIME;
DECLARE @business_day_hours FLOAT;

DECLARE @num1 FLOAT
DECLARE @num2 FLOAT
DECLARE @num3 FLOAT

SET @meeting_day = CONVERT(VARCHAR(10),@meeting_date,101);
SET @meeting_time =  CONVERT(VARCHAR(8),@meeting_date,108);

SET @submit_day = CONVERT(VARCHAR(10),GETDATE(),101);
SET @submit_time =  CONVERT(VARCHAR(8),GETDATE(),108);

SET @start_time_of_business_day = '09:00';
SET @business_day_hours = 8.5;

SET @num1 = ((DATEDIFF(dd, @submit_day, @meeting_day))
-(DATEDIFF(wk, @submit_day, @meeting_day) * 2)
-(CASE WHEN DATEPART(dw, @submit_day) = 1 THEN 1 ELSE 0 END)
-(CASE WHEN DATEPART(dw, @meeting_day) = 7 THEN 1 ELSE 0 END)
-(SELECT COUNT(*) FROM bank_holiday WHERE the_date BETWEEN @submit_day AND @meeting_day)) * @business_day_hours
SET @num2 = (select datediff(minute, @start_time_of_business_day, @submit_time)) / 60.0
SET @num3 = (select datediff(minute, @start_time_of_business_day, @meeting_time)) / 60.0

select @num1 - @num2 + @num3 as [hours]

OTHER TIPS

You can start SQL Server Profiler and see for yourself what parameters are passed to your procedure.

To quote an answer on "How does SQL Server decide format for implicit datetime conversion?"

"This can depend on a variety of factors - the operating system's regional settings, the current user's language and dateformat settings. By default, Windows uses US English, and the user's settings are US English and MDY."

"Your best bet, always, is to use ISO standard, non-regional, safe, unambiguous date formats like YYYYMMDD for dates and YYYY-MM-DDTHH:MM:SS[.mmm] for date+time."

I would, if yet possible, change string to DateTime in your web service interface and check sql trace to make sure that call is corresponding to what you are executing manually from the management studio.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top