2015-12-04 3 views
1

Я пытаюсь создать процедуру проверки годовых дат. Дата хранится один раз в BD, но в календаре моей winform он отображается ежегодно (я использую ежегодные полужирные даты на C#). Итак, что я хочу сделать с запросом, это проверить месяц и день, как дата, хранящаяся в таблице, но не работает. Это мой запрос:Процедура проверки годовой даты

SELECT IdCalendar, 
     Description, 
     DateCalendar, 
     Annualy 
FROM Calendar 
WHERE 
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,@DateCalendar)) AND 
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,@DateCalendar)) 

И, например, мой хранятся DateCalendar является '2015-12-04', и я мой paramenter @DateCalendar является '2016-12-04'. Любая идея о том, как сделать лучший запрос?

EDIT

Запрос не имеет какой-либо ошибки или предупреждения. Просто возвращает 0 строк. И мой DateCalendar хранится как DateTime.

СП:

CREATE PROC [dbo].[usp_app_Calendar_Search] 
@DateCalendar DATETIME, 
@Result  SMALLINT OUTPUT, 
@Message  VARCHAR(1000) OUTPUT 

AS 
BEGIN 
    DECLARE @vResult SMALLINT, @vMessage VARCHAR(1000) 
SELECT @vResult = 0, @vMessage = '' 

BEGIN TRY 
IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = @DateCalendar) 
BEGIN 
     IF(@DateCalendar = 0) SET @DateCalendar = NULL 
SELECT IdCalendar, 
     Description, 
     DateCalendar, 
     Annualy 
FROM Calendar 
WHERE 
(DATEPART(MONTH,DateCalendar) like DATEPART(MONTH,@DateCalendar)) AND 
(DATEPART(DAY,DateCalendar) like DATEPART(DAY,@DateCalendar)) 
SET @vResult = 1 
     SET @vMessage = 'Done' 
    END 
    ELSE BEGIN 

     SET @vResult = 0 
     SET @vMessage = 'Error.' 

    END 
END TRY 
BEGIN CATCH 

    SET @vResult = -1 
    SET @vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: ' + CAST(ERROR_LINE() AS VARCHAR) 

END CATCH 

SELECT @Result = @vResult, @Message = @vMessage 
END 

Спасибо заранее.

+0

'WHERE DATEPART (МЕСЯЦ, DateCalendar) = DATEPART (МЕСЯЦ, @ DateCalendar) И DATEPART (DAY, DateCalendar) = DATEPART (DAY , @ DateCalendar) ' – lad2025

+0

Я пробовал с этим, но не работает @ lad2025 – Coeus

+0

Будь конкретным. Плохие результаты/Нет результатов вообще/ошибка/предупреждение? Как вы храните свой 'DateCalendar' DATE/DATETIME/VARCHAR? – lad2025

ответ

1

Проблема с IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = @DateCalendar). Я переписать SP:

CREATE PROC [dbo].[usp_app_Calendar_Search] 
    @DateCalendar DATETIME, 
    @Result  SMALLINT OUTPUT, 
    @Message  VARCHAR(1000) OUTPUT 
AS 
BEGIN 
DECLARE @vResult SMALLINT = 0 
     ,@vMessage VARCHAR(1000) = ''; 

IF(@DateCalendar = 0) SET @DateCalendar = NULL; 

BEGIN TRY 
    SELECT IdCalendar, 
     Description, 
     DateCalendar, 
     Annualy 
    FROM Calendar 
    WHERE DATEPART(MONTH,DateCalendar) = DATEPART(MONTH,@DateCalendar) 
    AND DATEPART(DAY,DateCalendar) = DATEPART(DAY,@DateCalendar); 

    IF @@ROWCOUNT > 0 
    SELECT @vResult = 1, @vMessage = 'Done' 
    ELSE 
    SELECT @vResult = 0, @vMessage = 'Error.'; 
END TRY 
BEGIN CATCH 
    SET @vResult = -1 
    SET @vMessage = 'Error: ' + ERROR_MESSAGE() + ' Line: ' 
        + CAST(ERROR_LINE() AS VARCHAR) 
END CATCH 

SELECT @Result = @vResult, @Message = @vMessage; 

END 

EDIT:

Теперь условие WHERE не-SARGable так это означает, что оптимизатор запросов будет показывать индекс по DateCalendar колонке (если существует какой-либо).

Вы можете использовать вычисляемые столбцы, как @Tom Page предложил в комментарии:

ALTER TABLE Calendar ADD MonthCalendar AS DATEPART(MONTH,DateCalendar); 
ALTER TABLE Calendar ADD DayCalendar AS DATEPART(day,DateCalendar); 

/*Create Index on Calculated Columns for Month and day*/ 
CREATE INDEX IX_Calendar_Month_Day ON Calendar(MonthCalendar , DayCalendar); 

/*Use Computed Column Index in W*/ 
DECLARE @DateCalendar datetime = '2015-12-25'; 

SELECT IdCalendar, Description, DateCalendar, Annualy 
FROM Calendar 
WHERE MonthCalendar = DATEPART(MONTH,@DateCalendar) 
    AND DayCalendar = DATEPART(DAY,@DateCalenda); 
+1

отлично! Я думаю, что то же самое с вами комментарий IF EXISTS (SELECT * FROM Calendar WHERE DateCalendar = @DateCalendar) спасибо! : D – Coeus

+1

Попробуйте /* Создание вычисляемых столбцов на месяц и день */ ALTER TABLE Календарь ADD MonthCalendar AS DATEPART (МЕСЯЦ, DateCalendar) ALTER TABLE Календарь ADD DayCalendar AS DATEPART (день, DateCalendar) GO /* Создать индекс на вычисляемых столбцов за месяц и день */ CREATE INDEX IX_Calendar_Month_Day календарным (MonthCalendar, DayCalendar) GO /* Использование компьютерной Индекс столбца в W */ DECLARE @DateCalendar DateTime = '2015-12-25' ВЫБРАТЬ IdCalendar, Описание, DateCalendar, Annualy FROM Calendar WHERE MonthCalendar = DATEPART (месяц, @ DateCalendar) И DayCalendar = DATEPART (DAY, @ DateCalenda –

+0

@TomPage Хорошая точка. – lad2025

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