Хранимая процедура SQL Server, передающая год datepart в качестве параметра

Мне было интересно, может ли кто-нибудь помочь, пожалуйста, у меня есть процедура ниже, я пытаюсь включить ее, чтобы конечный пользователь мог передать только часть года даты, и он будет запрашивать на основе этого параметра, поэтому на данный момент Я запрашиваю между ContractDate.ContractDate >= 01/01/2015 AND <= 31/12/2015, но я хотел бы, чтобы наши пользователи могли вводить «2016», например, в текстовое поле в качестве параметра, который передается, и обновлял бы часть года в вышеуказанных критериях запроса на основе этого, но оставляя месяц и дневная часть цела, так они могут войти

Я совсем новичок, когда дело доходит до sql, поэтому любая помощь с радостью приветствуется.

SELECT TOP 100 PERCENT 
    dbo.Users.LoginName, 
    CAST(DATENAME(m, dbo.ContractDate.ContractDate) AS varchar) AS DatePeriod, 
    SUM(CASE WHEN dbo.Contract.Contract = 1 THEN 1 ELSE 0 END) AS Contract, 
    SUM(CASE WHEN dbo.contract.contract = 0 THEN 1 ELSE 0 END) AS Permanent
FROM
    dbo.ContractSkill 
INNER JOIN
    dbo.Users 
INNER JOIN
    dbo.Contract ON dbo.Users.UserId = dbo.Contract.UserId   
INNER JOIN
    dbo.ContractDate ON dbo.Contract.ContractId =   dbo.ContractDate.ContractId 
    ON dbo.ContractSkill.ContractId = dbo.Contract.ContractId
WHERE        
    (dbo.ContractDate.DNS = 0) 
    AND (dbo.ContractSkill.SkillId = 30960)    
    AND (dbo.ContractDate.ContractDate >= CONVERT(DATETIME, '2015-01-01  00:00:00', 102)) 
    AND (dbo.ContractDate.ContractDate <= convert(DATETIME, '2015-12-31 00:00:00', 102))
GROUP BY 
    CAST(DATENAME(m, dbo.ContractDate.ContractDate) AS varchar),
    MONTH(dbo.ContractDate.ContractDate), dbo.Users.LoginName
    ORDER BY MONTH(dbo.ContractDate.ContractDate)

person Gemma Scully    schedule 04.11.2016    source источник
comment
Вместо этого вы можете использовать Year(dbo.Contract .ContractDate) = 2015   -  person Shell    schedule 04.11.2016
comment
Похоже, вам не хватает части присоединения к ContractSkill для пользователей.   -  person Neo    schedule 04.11.2016
comment
Почему вы используете лучшие 100 процентов? Я думаю, что вы можете удалить это тоже.   -  person Neo    schedule 04.11.2016
comment
Hi Shell, Если я использую это, он будет выполнять запрос с начала 2015 года до конца 2015 года? Если бы это было так, я бы смог передать #Year в качестве параметра и сказать, что Year(contract.contractdate) = #Year   -  person Gemma Scully    schedule 04.11.2016
comment
@GemmaScully да, если вы хотите показать все данные за определенный год, вам просто нужно передать параметр только для года. т.е. @Contract_Year tinyint.   -  person Shell    schedule 04.11.2016
comment
Where Year(dbo.Contract.ContractDate) = @Contract_Year вот так.   -  person Shell    schedule 04.11.2016
comment
@Shell Я немного подумал об этом :-/ Вы должны опубликовать это как ответ   -  person Neo    schedule 04.11.2016
comment
Отлично - большое спасибо вам обоим!   -  person Gemma Scully    schedule 04.11.2016
comment
Вредные привычки: объявление VARCHAR без (длины) — вы должны всегда указывать длину для любых varchar переменных и параметров, которые вы используете   -  person marc_s    schedule 04.11.2016


Ответы (2)


Есть два способа добиться этого.


Первый вариант очень прост: передается параметр только для года

@Contract_Year tityint

затем поместите условие where с функцией Year().

Where Year(dbo.Contract.ContractDate) = @Contract_Year

Второй – создание двух отдельных переменных для значений "Дата начала" и "Дата окончания".

Я бы рекомендовал использовать этот метод, если вы создали индекс для поля ContractDate. Тем не менее, индекс не будет учитываться, если вы используете поле внутри какой-либо функции (например, Year(), Month() или Day()).

Паремтер

@Contract_Year Char(4)

Код хранимой процедуры

Declare @from_Date DateTime = Cast(@Contract_Year + '-01-01' As DateTime);
Declare @to_Date DateTime = Cast(@Contract_Year + '-12-31 23:59:59' As DateTime);

Используйте указанную выше переменную в предложении Where

Where (dbo.Contract.ContractDate Between @from_Date and @to_Date)
person Shell    schedule 04.11.2016

Если вы имеете в виду, что вы будете добавлять параметр в свою функцию, через которую предоставляется выбранный год, просто добавьте этот параметр и:

  1. Объявите две переменные, которые будут использоваться в операторе выбора, тип которого DATE,

  2. Добавьте следующие задания:

    SET @YourStartVariable = CONVERT(DATETIME,CONCAT(P_Passed_Year,'-01-01 00:00:00'),102);
    SET @YourEndtVariable  = CONVERT(DATETIME,CONCAT(P_Passed_Year,'-31-12 23:59:59'),102);
    
  3. Используйте эти переменные в своем запросе, что означает, что вместо:

    (dbo.ContractDate.ContractDate >= CONVERT(DATETIME,'2015-01-01 00:00:00', 102))
    AND (dbo.ContractDate.ContractDate <= convert(DATETIME,'2015-12-31 00:00:00', 102))
    

    вам придется:

    (dbo.ContractDate.ContractDate >=  @YourStartVariable)
    AND (dbo.ContractDate.ContractDate <=  @YourEndVariable)
    

То есть.

Ваш первоначальный верхний предел был YYYY-12-31 00:00:00, и я предполагаю, что он должен быть YYYY-12-31 23:59:59.

person FDavidov    schedule 04.11.2016