2015-07-09 2 views
1

У меня есть правильные выходы для этих функций. Рассчитывает ли датифик только разницу дней в днях в том же месяце? Когда я перехожу в дате в форме '01 января 2015 года, она всегда посылает мне обратно 0 =/я пропустил что-то в своей логике или синтаксисе?Неисправность при расчете TSQL-date diff дает мне неприятности

CREATE FUNCTION dbo.CanPolicy 
(
    @ReservationID int, 
    @CancellationDate date 
) 
RETURNS smallmoney 
AS 
    BEGIN 
     DECLARE @DepositPaid smallmoney 
     SET @DepositPaid = (SELECT ResDepositPaid 
          FROM Reservation 
          WHERE ReservationID = @ReservationID) 
     DECLARE @ResDate date 
     SET @ResDate = (SELECT ResDate 
         FROM Reservation 
         WHERE ReservationID = @ReservationID) 
     DECLARE @CanceledDaysAhead int 
     SET @CanceledDaysAhead = DATEDIFF(day, @ResDate, @CancellationDate) 
     DECLARE @result smallmoney 
     SET @result = 0 
     SET @result = CASE WHEN @CanceledDaysAhead > 30 THEN 0 
         WHEN @CanceledDaysAhead BETWEEN 14 AND 30 THEN @DepositPaid * 0.25 + 25 
         WHEN @CanceledDaysAhead BETWEEN 8 AND 13 THEN @DepositPaid * 0.50 + 25 
         ELSE @DepositPaid 
        END 
     RETURN @result 
    END 

GO 
+0

Вы сказали, что получаете ошибку, когда '@CancellationDate = 01 января 2015', пожалуйста, укажите значение' ResDate', которое используется в расчете .. – Deepshikha

+1

Не знаю всех параметров тестового сценария, но я думаю параметры датированного параметра необходимо переключить: 'DATEDIFF (день, @CancellationDate, @ResDate)' В противном случае, если датой отмены является до момента резервирования, lateiff всегда будет возвращать отрицательное значение, делая неверные результаты «case». –

+0

Кроме того, вы можете получить depostipaid и resdate за один раз: 'SELECT @DepositPaid = ResDepositPaid, @ResDate = ResDate FROM Reservation WHERE ReservationID = @ ReservationID' –

ответ

1

Нет, DATEDIFF подсчитывает даты между ними. Попробуйте:

SELECT DATEDIFF(day,{ts'2105-01-01 00:00:00'},{ts'2105-04-01 00:00:00'}) 

Может быть проблема формата даты ...

Вы уверены, что @ResDate установлен правильно?

EDIT: Новый подход с КТР

DECLARE @ReservationID INT=123; 
DECLARE @CancelationDate DATE=GETDATE(); 

WITH ReservationCTE AS 
(
    SELECT ResDepositPaid 
      ,ResDate 
    FROM Reservation 
    WHERE [email protected] --assuming that ReservationID is a unique key! 
) 
,ReservationCTEWithDateDiff AS 
(
    SELECT ReservationCTE.* 
      --EDIT: switched dates due to a comment by Me.Name 
      ,DATEDIFF(DAY,@CancelationDate,ResDate) AS CanceledDaysAhead 
    FROM ReservationCTE 
) 
SELECT CASE WHEN CanceledDaysAhead>30 THEN 0 
      WHEN CanceledDaysAhead BETWEEN 14 AND 30 THEN ResDepositPaid * 0.25 + 25 
      WHEN CanceledDaysAhead BETWEEN 8 AND 13 THEN ResDepositPaid * 0.50 + 25 
      ELSE ResDepositPaid END AS MyReturnValue 
FROM ReservationCTEWithDateDiff 
+0

@ResDate принимает значение из моего выбора, который находится в моей БД, как «дата». Дает ли дата в целом даты хранения в том же формате, если они являются одним и тем же типом данных? Или, если есть, например, две даты, они каким-то образом могут храниться по-разному и конфликтуют по сравнению с DATEDIFF? Изменить: добавлены запятые, чтобы сделать мой вопрос более понятным. Изменить: сообщит вам, работает ли {}, не удается подключиться к удаленному db. Не игнорируя ваш мыслительный ввод =) –

+0

Я дал вам еще один подход, который намного лучше в производительности (особенно если «Резервация» заполнена множеством строк ... Попробуй попробовать .. и, пожалуйста, проголосуйте, если помогло thx – Shnugo

+0

, Позвольте мне подняться.Я новичок здесь, но я помню, чтобы вернуться и укрепить его, как только я встану до 15. Если это конечно! Еще раз спасибо за продуманный ввод! –

1

Я думаю, что правильный и короткий вариант вашей функции это - пожалуйста, дайте ему попробовать:

CREATE FUNCTION dbo.CanPolicy 
(
    @ReservationID int, 
    @CancellationDate date 
) 
RETURNS smallmoney 
AS 
    BEGIN 
     DECLARE @DepositPaid smallmoney, 
       @CanceledDaysAhead int 

     SELECT @DepositPaid = ResDepositPaid, 
       @CanceledDaysAhead = DATEDIFF(DAY,ResDate,@CancellationDate) 
     FROM Reservation 
     WHERE ReservationID = @ReservationID 


     RETURN CAST(CASE WHEN @CanceledDaysAhead > 30 THEN 0 ELSE 
       CASE WHEN @CanceledDaysAhead BETWEEN 14 AND 30 THEN @DepositPaid * 0.25 + 25 ELSE 
       CASE WHEN @CanceledDaysAhead BETWEEN 8 AND 13 THEN @DepositPaid * 0.50 + 25 ELSE 
       @DepositPaid END END END AS smallmoney) 

    END 
GO 

Основная проблема была ваша регистру когда блок я думаю ...

+0

Проблема закончилась DATEDIFF, хотя я новичок в SQL. Лучше ли использовать «КОНЕЦ» для КАЖДОГО «КОГДА»? –

+0

'CASE WHEN THEN ELSE END' – CeOnSql

0

Возможно, вы решили это сейчас, однако один из способов, которым я справился с расписанием даты, не заботясь о том, чтобы разница была + или - значение - использовать ABS:

ABS on MSDN

Таким образом, сазе не нужно различать между ними.

Смежные вопросы