2013-01-03 2 views
-3

`직원이 언제 작업을 시작했는지 나타내는 시작일 열 (s_date)이있는 테이블 (workers)이 있습니다. 그래서 나는 그것이 일년 (365 일) 일할 경우 예외를 줄 수있는 방아쇠를 만들고 싶습니다. 그러나 코드에 문제가 있습니다. 어떤 도움?PostgreSQL의 날짜 빼기

CREATE OR REPLACE FUNCTION control_func() RETURNS TRIGGER AS ' 
declare 
int1 integer; 
tt Date; 
begin 
select now()::date into tt; 
select s_date from workers; 
if(tt-s_date<365) then 
RAISE EXCEPTION ''A message''; 
end if; 
RETURN NULL; 
END; 
' LANGUAGE 'plpgsql'; 
+0

가있는 경우 오류가 무엇입니까? now()와 a_date에'date_part'를 써서는 안됩니까? – bonCodigo

+1

@bonCodigo : 표현식'now() :: date'는 날짜 만 반환합니다. CURRENT_DATE를 사용하는 것이 더 좋습니다. –

+0

@Catcall : 'current_date'를 사용하면 캐스팅 할 때 발생할 수있는 [시간대 문제] (http://stackoverflow.com/a/12994322/479863)도 피할 수 있습니다. –

답변

4

If Datediff(days, tt, ss) < 365 then

, s_datess 말을 저장하는 또 다른 변수를 추가합니다. 우선, 단지 큰 혼란을 만드는 함수 본문을 인용하는 대신 dollar quoting을 사용하는 작은 따옴표를 사용하지 마십시오

select s_date from workers; 

:

create or replace function f() returns trigger as $$ 
    ... 
$$ language plpgsql; 

다음이 유용 아무것도하지 않습니다 그러면 모든 s_date 값을 workers에서 가져 와서 모두 버리려고합니다. 당신은 트리거 현재 행을보고 싶은 그 NEW에서 사용할 수 :

NEW
데이터 형식 RECORD; 행 수준 트리거에서 INSERT/UPDATE 조작에 대한 새 데이터베이스 행을 보유하는 변수. 이 변수는 명령문 레벨 트리거와 DELETE 조작에 대해 NULL입니다.

그래서 당신은 당신이 관심있는 날짜를 볼 수 new.s_date 볼 수 있습니다 : 당신이 여기 return null;을 원하지 않는, 그래서 이것은 아마 행 수준 before insert or update 트리거입니다

select now()::date into tt; 
if tt - new.s_date < 365 then 
    raise exception 'A message'; 
end if; 

을; fine manual에서 :

작업 전에 해고 행 레벨 트리거는 다음과 같은 선택 사항이 있습니다

  • 그것은 현재 행에 대한 작업을 건너 NULL을 반환 할 수 있습니다. 이것은 실행 프로그램이 트리거를 호출 한 행 레벨 조작 (특정 테이블 행의 삽입, 수정 또는 h 제)을 수행하지 않도록 지시합니다.
  • 행 수준 INSERTUPDATE 트리거의 경우에만 반환 된 행이 삽입 될 행이되거나 업데이트되는 행을 대체합니다. 이렇게하면 트리거 함수가 삽입 또는 업데이트되는 행을 수정할 수 있습니다.

그래서 당신의 return null;은 그 당신이 원하는 아니다 "새 레코드가 유효한 경우이 INSERT 또는 UPDATE를 건너"를 의미한다. return new;을 원합니다.

또한 사용하지 않은 변수가 있습니다.그리고 tt 대신 current_date을 사용할 수 있습니다.

귀하의 기능은 더 다음과 같아야합니다

create or replace function control_func() returns trigger as $$ 
begin 
    if current_date - new.s_date < 365 then 
     raise exception 'A message'; 
    end if; 
    return new; 
end; 
$$ language plpgsql; 
0

편집 : 초기 구문은 datediff으로되어 있습니다. 그러나 그것은 MYSQL 구문입니다. 따라서 위의 상세하고 정확한 대답으로 당신은 더 낫습니다. ;-) 당신이 코드에서

타이이이, 당신은 몇 가지 문제가

+0

당신은'date_part'가 필요하지 않습니다. PostgreSQL에서 두 개의'date'의 차이점은 [그들 사이의 날짜 수]입니다 (http://www.postgresql.org/docs/current/interactive/functions-datetime. html # 운영자 - 날짜 - 시간 표). –

+0

@muistooshort 나는 그것을 모바일에서 타이프하고 내려 갔다. 사전은'datediff'를'date_part'로 뒤집습니다. 당신이 분명히'Datediff' 문법으로 더 있음을 눈치 챘을 지 모르겠지만, 이것은 POSTGRES가 MYSQL이 아니라는 것을 깨달았습니다 .... :-) – bonCodigo