2011-12-30 2 views
1

SQL 사용자 정의 함수를 작성하여 주어진 날짜가 일본 휴일인지 판별했습니다. 이제는 * n * 번에 동일한 인라인보기를 호출하는 함수의 괴물로 이루어져 있으며 매우 현명하지 않습니다. 최고의 실생활 솔루션이 달력 테이블을 만드는 것이라는 것을 알고 있지만 필자가 작성한 모든 코드 라인을 스크랩하지는 않을 것입니다. 나는 리팩토링 아이디어를 기대합니다. 감사.인라인 뷰를 사용하지 않고 아이디어 리팩토링?

기능 isholiday (d)에는 3 가지 기능이 있습니다. 각각 3 종류의 일본 휴일을 정의합니다.

DELIMITER // 
CREATE FUNCTION isholiday(d date) RETURNS int 
BEGIN 
DECLARE t int; 
CASE WHEN isregularholiday(d) = 1 
      THEN SET t = 1; 
    WHEN iscarryoverholiday(d) = 1 
      THEN SET t = 1; 
    WHEN isdentholiday(d) = 1 
      THEN SET t = 1; 
    ELSE SET t = 0; END CASE; 
RETURN t; 
END 
// 

isregularholiday (d)는 다음과 같다 : 직접 HOLIDAY_DATE 열과 일치하지

DELIMITER // 
CREATE FUNCTION isregularholiday(d date) RETURNS int 
BEGIN 
DECLARE s int; 
DECLARE t int; 
SELECT count(*) INTO s 
    FROM (SELECT holiday_desc 
      , CASE WHEN SUBSTR(holiday_date, 3, 1) = '-' 
         THEN CAST(CONCAT_WS('-', YEAR(d), holiday_date) AS DATE) 
        WHEN holiday_date = 'ATH21' 
         THEN ATHLETIC_DATE(d) 
    /*There are six mobile holidays but I shall spare you the other five. */  
       ELSE NULL END cnvt 
      FROM holidays 
     WHERE YEAR(d) BETWEEN valid_from AND valid_to) **base** 
WHERE cnvt = d; 
CASE s WHEN 1 THEN SET t = 1; 
     ELSE SET t = 0; 
END CASE; 
RETURN t; 
END 
// 

함수 인수 D (또는 월 최신 값) (참조 cnvt = d) 정확한 때문에 일부 휴일의 날짜는 기능적으로 연도에 따라 달라 지므로 여러 함수로 분기되는 CASE식이 달라집니다. 이 기능은 인라인보기 베이스을 항상 참조합니다.

이제 기본 휴일 외에 두 가지 유형의 휴일이 있으며 변덕 스럽습니다. 나는 임시로 이월 휴가라고 부르고 휴일을 쉬었다. 이월 휴가는 다음과 같이 정의됩니다. 휴일 H가 일요일에 해당하는 경우 첫 번째 비휴 공휴일은 H의 이월 휴가입니다. 몇 개의 공휴일이 함께 고정되므로 H의 첫 번째 비휴 공휴일은 반드시 다음날 또는 월요일.

덴트 휴일은 두 휴일 사이의 평일입니다. 이월은 채권 할인보다 우선합니다.

모바일 휴일로 인해 두 가지 유형의 공휴일은 모두 이동식이며 변덕스러운 것으로 계산해야합니다. iscarryoverholiday (d) 을 쿼리하고 d와 d 사이의 일요일 사이의 범위에 대한 행 수를 계산합니다. 카운트가 d와 마지막 일요일 사이의 날짜 차이와 같으면 d는 이월 휴일입니다.

isdentholiday (d) d, d-1 및 d + 1에 대해 isregularholiday()를 호출합니다 (각 인수의 기대 값은 0, 1, 1 임). 또한 iscarryoverholiday()를 d (0을 얻음)에 호출하므로 베이스을 네 번 읽습니다. 아 ....

더 이상의 세부 정보는 제공하지 않겠습니다. 나는 똑똑한 것을 할 수 있고 MySQL의 동적 뷰에 가장 가까운 것을 정의 할 수 있는지 궁금하다.

지금까지 읽어 주셔서 감사합니다.

여기에 사용 된 휴가는 일요일을 제외합니다.

+3

는 "나는 내가 가진 모든 코드 라인을 폐기 감히하지 않을 ... 당신은 후자를 할 수있을 것으로 보인다, 그래서 아마 당신은해야 쓴". 당신은 대답했고 자신을 무시했습니다. 왜 우리가 신경 써야합니까? – gbn

+3

"필자가 작성한 모든 코드 라인을 스크랩하지 않을 것입니다." 왜 더 나은 것이 나오면 어떨까요? (필자는 오라클이 이미 제공되는 문자열의 모든 단어의 첫 글자를 대문자로 쓰기 위해 오라클에 사용자 정의 함수를 작성했다. 필자는 오라클이 이미 그 함수를 가지고 있을지도 모르는 상태에서 f_initcap이라는 함수를 호출했다.) In 어떤 경우 든 기존 코드를 삭제할 필요가 없습니다. 그냥 사용을 중지하십시오. –

답변

0

저는 Holiday List라는 스크립트를 작성했습니다. 기본적으로, 이는 매개 변수로 1 년이 전달되는 테이블 UDF이며 휴일을 찾기 위해 결합 할 수있는 "휴일 테이블"을 리턴합니다. 이렇게하면 시작점과 휴일에 대처하는 방법에 대한 몇 가지 생각을 줄 수있는, 당신은 당신이 스크립트를 원하는 경우에 ... 스크립트 일본 휴일

http://www.sqlservercentral.com/scripts/Date+Manipulation/74302/

을 규칙을 추가 할 수 없습니다 수 위의 링크에서 가져와 알려 주시면 이메일로 보내 드리겠습니다 ...스크립트가 마이크로 소프트 SQL 위해 작성, 그것은 MySQL의에서 작동하는 코드 변경의 조금 걸릴 수 있지만,

+0

코드를 살펴 보았습니다. 중요한 부분이 테이블을 반환하는 UDF 인 것처럼 보입니다. 영리한 MySQL 해결 방법은 무엇입니까? – amemus

+0

mySQL을 잘 알지는 못한다. mySQLguru 중 하나가 곧 뛰어나다. 새해 복 많이 받으세요. – Sparky

1

달력 테이블 어떤을 이없는 스크립트에 너무 공상 아무것도 없다 논리. 한 번 채우면 그게 전부입니다.

공휴일을 매일 계산하여 저장하더라도 (공휴일이 아닌 날을 포함하여) 세기 일 경우에도 여전히 0.5MB 미만의 디스크 공간을 사용합니다.

date    DATE, 
isHoliday   TINYINT, 
isRegularHoliday TINYINT, 
isCarryOverHoliday TINYINT, 
isDentHoliday  TINYINT 

적절한 색인을 추가 한 후에도 여전히 2 메가 바이트 만 사용합니다.

PK     (date) 
IX_HOLIDAY   (isHoliday, date) 
IX_RegularHoliday (isRegularHoliday, date) 
IX_CarryOverHoliday (isCarryOverHoliday, date) 
IX_DentHoliday  (isDentHoliday, date) 

이 테이블에 가입하면 날짜가 특정 휴일 유형인지 여부를 확인할 수 있습니다. 원하는 경우 is????Holiday() 함수에서 해당 테이블을 사용할 수도 있습니다.

이것은 상수 계산과 상수 저장의 가장 좋은 예입니다. 내가 제일 실제 솔루션은 일정 테이블을 구축하는 것입니다 알고 있지만

관련 문제