2015-08-26 4 views
1

У меня есть отчет, который принимает YEAR как один параметр, и я хотел рассчитать начало и конец финансового года. Вот как я пытаюсь:Рассчитать дату начала и окончания финансового года на основе введенного года SQL Server и SSRS

CREATE PROCEDURE [dbo].[sp_name] 
    @StartDate as datetime, 
    @Enddate as datetime, 
    @year as varchar(10) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    @StartDate = year(dateadd(q, -1, cast(cast(@year AS char) + '/01/' + cast(@year AS char) AS datetime))) = @year 

Это правильный способ сделать это?

Мне нужна дата финансового начала с 1 июля 2014 года по 30 июня 2015 года, если год введен как 2015. Пожалуйста, обратите внимание, что это необходимо для внутреннего расчета в сценарии. Если я что-то делаю неправильно, как я могу исправить это, чтобы получить желаемые результаты?

+5

Сторона примечания: вы не должны ** использовать префикс 'sp_' для ваших хранимых процедур. Microsoft [зарезервировала этот префикс для собственного использования (см. * Именование сохраненных процедур *)] (http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx) и вы рискуете столкнуться с именем когда-нибудь в будущем. [Это также плохо для производительности вашей хранимой процедуры] (http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix). Лучше просто просто избегать 'sp_' и использовать что-то еще в качестве префикса - или никакого префикса вообще! –

+2

Также: '@ year' действительно всегда является ** числовым ** значением - так почему вы объявляете этот параметр как' varchar (10) 'then ?? Используйте ** наиболее подходящий тип данных ** - здесь используется «INT». –

+0

Спасибо. Я исправлю все это во время моей реальной реализации. – AskMe

ответ

2

Использование DATEADD и DATEDIFF вы можете компьютер для ваших финансовых лет:

DECLARE @year INT = 2015 

SELECT 
    start_date = DATEADD(MONTH, 6, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(YEAR, @year - 1900, 0)) - 1, 0)), 
    end_date = DATEADD(DAY, -1, DATEADD(MONTH, 6, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(YEAR, @year - 1900, 0)), 0))) 

Read here для более общих дат процедур.


Чтобы использовать это в хранимой процедуре:

CREATE PROCEDURE procedure_name 
    @year AS INT 
AS 
BEGIN 
SET NOCOUNT ON 

SELECT 
    start_date = DATEADD(MONTH, 6, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(YEAR, @year - 1900, 0)) - 1, 0)), 
    end_date = DATEADD(DAY, -1, DATEADD(MONTH, 6, DATEADD(YEAR, DATEDIFF(YEAR, 0, DATEADD(YEAR, @year - 1900, 0)), 0))) 

END 
+0

Я использую SQL 2008. Это дает результаты как 1 июля 2014 года 12:00 и 30 июня 2015 года 12:00. Отчет с этим параметром возвращает меньше записей. Тем не менее, отчет, запущенный с этим «1-JUL-2014» и «30-июль-2015», возвращает больше номеров записей, это я считаю правильным. Итак, как я могу сделать начальную и конечную дату как «1-JUL-2014» и «30 -JUN-2015»? – AskMe

0

Для SQL Server 2012+ версии, вы можете использовать DATEFROMPARTS https://msdn.microsoft.com/en-IN/library/hh213228.aspx

CREATE PROCEDURE [dbo].[usp_name] 
    @StartDate as datetime, 
    @Enddate as datetime, 
    @year as int 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    SELECT @StartDate = DATEFROMPARTS(@year-1,7,1), @EndDate=DATEFROMPARTS(@year,6,30) 
END 
+0

Я использую Sql server 2008. Нужно решение, которое работает в версии 2008 года. – AskMe

0

Возможно, это поможет и также работает, когда финансовый год изменился или вы перейдете в новую компанию.

CREATE PROCEDURE [dbo].[usp_yeardates] /* or your sp name */ 
    @year AS SMALLINT, 
    @monthoffset AS TINYINT = 0, /* if you wish your year to start at a month other than jan then set number of months to offset, e.g. to start April, move three forward @monthoffset = 3 */ 
    @startdate AS SMALLDATETIME OUTPUT, /* NB 2008r2+ use DATE instead of SMALLDATETIME */ 
    @enddate AS SMALLDATETIME OUTPUT 
AS 

/* Created by Darren Edward Comeau - 26/08/2015 */ 

BEGIN 

    /* check inputs */ 
    IF @year < 1900 or @year > 2078 
     RAISERROR ('year out of bounds',16,1) 

    ELSE IF @monthoffset > 11 
     RAISERROR ('monthoffset out of bounds',16,2) 

    ELSE 
     SELECT 
      /* logic to establish start/end date */ 
      @startdate = 
       dateadd(month,@monthoffset, 
        dateadd(year,@year-1900,'19000101') 
       ), 
      @enddate = 
       dateadd(day,-1, 
        dateadd(month,@monthoffset, 
         dateadd(year,@year-1899,'19000101') 
        ) 
       ); 

END; 
GO 

Вы должны использовать следующую процедуру:

/* usage */ 
DECLARE 
    @startdate SMALLDATETIME, 
    @enddate SMALLDATETIME, 
    @year SMALLINT, 
    @monthoffset TINYINT, 
    @rc INT; 

EXEC @rc = usp_yeardates 
    @year = 2011, 
    @monthoffset = 6, /* 6 months offset equalls July - June year */ 
    @startdate = @startdate OUTPUT, 
    @enddate = @enddate OUTPUT; 

SELECT 
    @rc AS [ReturnCode], 
    @startdate AS [StartDate], 
    @enddate AS [EndDate]; 
+0

Ваша проблема с ограничениями по дате, вероятно, относится к последнему дню месяца, вы исключаете записи всего дня, если они включают в себя часть даты. Это можно решить двумя способами: использовать следующий день с последнего дня и использовать меньше, чем

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