2023.01.24 - [개발/Windows] - 배치 파일(.bat)과 작업 스케쥴러를 사용하여 To-Do 데이터 월간별 집계하기
배치 파일(.bat)과 작업 스케쥴러를 사용하여 To-Do 데이터 월간별 집계하기
SQL Server 에이전트를 이용해서 스케쥴러로 만들려고 했는 데 사용하고 있는 DB 호스팅 구독 버전에는 SQL Server 에이전트 사용 권한이 없어서 윈도 배치 파일과 작업 스케쥴러를 사용해서 저장된 To
hyangforest.tistory.com
매월 1일 오전 12시에 실행되는 SP입니다. 해당 연도와 월의 데이터가 존재하지 않으면 INSERT를 하고 존재하면 UPDATE를 실행합니다.
CREATE PROCEDURE [dbo].[sp_ROUTINE_Ups_ToDoMontlyStat]
(
@YYYY int = 0
, @MM int = 0
)
AS
BEGIN
DECLARE @_Date datetime
DECLARE @_ToDo_D_CNT int
DECLARE @_ToDo_C_CNT int
DECLARE @_ToDo_Y_CNT int
DECLARE @_ToDo_N_CNT int
-- 해당 연도-월의 총 일 수
SET @_Date = CONCAT(@YYYY, '-', FORMAT(@MM,'D2') , '-', '01')
--SELECT @_ToDo_D_CNT = DATEPART(day, DATEADD(day, -1, DATEADD(month, 1, @_Date)))
SELECT @_ToDo_D_CNT = DATEPART(day, EOMONTH(@_Date))
-- 해당 연도-월 총 기록 수
SELECT @_ToDo_C_CNT = COUNT(*)
FROM dbo.ToDo
WHERE YEAR(DoneDate) = @YYYY
AND MONTH(DoneDate) = @MM
GROUP BY YEAR(DoneDate), MONTH(DoneDate)
-- 해당 연도-월 총 달성 수
SELECT @_ToDo_Y_CNT = COUNT(*)
FROM dbo.ToDo
WHERE YEAR(DoneDate) = @YYYY
AND MONTH(DoneDate) = @MM
AND (Task1YN = 1 and Task2YN = 1 and Task3YN = 1)
GROUP BY YEAR(DoneDate), MONTH(DoneDate)
IF NOT EXISTS ( SELECT ToDo_YYYY
FROM dbo.ToDoMontlyStat
WHERE ToDo_YYYY = @YYYY
AND ToDo_MM = @MM)
BEGIN
INSERT INTO dbo.ToDoMontlyStat
(
ToDo_YYYY
, ToDo_MM
, ToDo_D_CNT
, ToDo_C_CNT
, ToDo_Y_CNT
, ToDo_N_CNT
, CreateDate
)
VALUES
(
@YYYY
, @MM
, @_ToDo_D_CNT
, @_ToDo_C_CNT
, @_ToDo_Y_CNT
, @_ToDo_C_CNT - @_ToDo_Y_CNT
, GETDATE()
)
END
ELSE
BEGIN
UPDATE dbo.ToDoMontlyStat
SET ToDo_YYYY = @YYYY
, ToDo_MM = @MM
, ToDo_D_CNT = @_ToDo_D_CNT
, ToDo_C_CNT = @_ToDo_C_CNT
, ToDo_Y_CNT = @_ToDo_Y_CNT
, ToDo_N_CNT = @_ToDo_C_CNT - @_ToDo_Y_CNT
, UpdateDate = GETDATE()
WHERE ToDo_YYYY = @YYYY
AND ToDo_MM = @MM
END
END
GO
사용한 함수
FORMAT
FORMAT(@MM,'D2') @MM이 데이터 타입이 int로 10자리 이하인 경우에는 1자리로 되면 datetime으로 변환할 때 오류가 날 줄 알고 0을 채웠는데, 정수로 넣어도 @_Date에 올바르게 datetime으로 변환됩니다.
DATEPART
지정한 날짜의 부분을 정수로 반환해 주는 함수입니다.
DATEPART ( datepart , date )
datepart 부분이 정수를 반환할 date 인수의 특정 부분입니다. 약어는 사용할 수 있지만 사용자 정의 변수 항목은 허용하지 않습니다.
사용예시)
year, quater, month, dayofyear, day, week, weekday, hour, minute, millisecond, microsecond, nanosecond, tzoffset, iso_week
date 인자는 데이터 타입이 date, datetime, datetimeoffset, datetime2, smalldatetime, time를 확인하며 계산 식이나, 문자열 리터럴, 사용자 정의 변수를 허용합니다.
DATEADD
지정한 날짜의 부분을 원하는 정수로 계산하여 수정된 날짜/시간 값을 반환하는 함수입니다. 반환 값의 데이터 형식은 제공된 인수에 따라 달라질 수 있습니다. 지정한 날짜의 데이터 형식이 문자열 리터럴로 표시한 날짜인 경우 datetime 값을 반환합니다.
DATEADD (datepart , number , date )
SELECT DATEADD(month, 1, '20230830');
SELECT DATEADD(month, 1, '2023-08-31');
-- 2023-09-30 00:00:00.000 datetime 반환
DATEPART(day, DATEADD(day, -1, DATEADD(month, 1, @_Date)))
@_Date = '2023-03-01'
STEP 1. DATEADD(month, 1, @_Date)
result : 2023-04-01 00:00:00.000
STEP 2. DATEADD(day, -1, STEP 1.result)
result :2023-03-31 00:00:00.000
STEP 3. DATEPART(day, STEP 2.result)
result : 31
EOMONTH
지정한 날짜가 포함된 달의 마지막 날을 반환하는 함수입니다. 선택 사항으로 추가적으로 계산할 월을 정수로 입력하면 해당하는 월의 마지막 날을 반환합니다.
EOMONTH ( start_date [, month_to_add ] )
DATEPART(day, EOMONTH(@_Date))
@_Date = '2023-03-01'
STEP 1. EOMONTH(@_Date)
result : 2023-03-31
STEP 2. DATEPART(day, EOMONTH(STEP 1.result))
result : 31
결과
exec sp_ROUTINE_Ups_ToDoMontlyStat 2023,1
작업 스케줄러로 SP를 실행하는 웹 페이지에서 SP 호출 파라미터는 현재에서 한 달 전의 값으로 전달하여 사용합니다.
사용예시)
2023년 2월 1일 오전 12시 작업 : sp_ROUTINE_Ups_ToDoMontlyStat 2023,1
참고사이트
https://learn.microsoft.com/ko-kr/sql/t-sql/functions/datepart-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/ko-kr/sql/t-sql/functions/dateadd-transact-sql?view=sql-server-ver16
https://learn.microsoft.com/ko-kr/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-ver16
'개발 > SQL Server' 카테고리의 다른 글
데이터베이스 개체 확장 속성 추가/조회/수정하기 (2) | 2023.10.28 |
---|---|
[SSMS] 쿼리 및 저장 프로시저 단축키 설정하여 사용하기 (0) | 2023.10.17 |
트랜잭션 로그로 원하는 시점에 데이터 복구하기 (0) | 2023.02.20 |
백업 된 DB 파일 자동 삭제 설정하기 (0) | 2023.01.27 |
CONVERT와 FORMAT 함수를 이용하여 날짜 데이터를 다양한 형식으로 표현하기 (0) | 2022.12.28 |