2016-07-24 11 views
-1

사전에 생성 된 트리거를 통해 파티션 테이블을 자동으로 만들었을 때 오류가 발생했습니다.gp 함수가 SELECT 문이 아닌 부분을 실행하기 때문에 세그먼트에서 실행할 수 없습니다.

enviorment 정보 :

GP 버전 : 4.3.8.1

오류 :

NOTICE: Found 2 data formatting errors (2 or more input rows). Rejected related input data. 
ERROR: function cannot execute on segment because it issues a non-SELECT statement (functions.c:135) (seg13 ZHJK-HADOOP-SLAVE6:40001 pid=19959) (cdbdisp.c:1326) 
DETAIL: 
SQL statement "CREATE TABLE T_FM_HISTORYALARM_20160101(CONSTRAINT T_FM_HISTORYALARM_20160101_eventtime_check CHECK (EVENTTIME >= timestamp '20160101000000' AND EVENTTIME < (timestamp '20160101000000' + interval '1 day')))INHERITS (T_FM_HISTORYALARM)" 
PL/pgSQL function "history_alarm_partition" line 36 at execute statement 
********** 错误 ********** 

ERROR: function cannot execute on segment because it issues a non-SELECT statement (functions.c:135) (seg13 ZHJK-HADOOP-SLAVE6:40001 pid=19959) (cdbdisp.c:1326) 
SQL 状态: XX000 
详细: 
SQL statement "CREATE TABLE T_FM_HISTORYALARM_20160101(CONSTRAINT T_FM_HISTORYALARM_20160101_eventtime_check CHECK (EVENTTIME >= timestamp '20160101000000' AND EVENTTIME < (timestamp '20160101000000' + interval '1 day')))INHERITS (T_FM_HISTORYALARM)" 
PL/pgSQL function "history_alarm_partition" line 36 at execute statement 

기능 코드 :

CREATE OR REPLACE FUNCTION history_alarm_partition() 
    RETURNS trigger AS 
$BODY$ 
DECLARE tbl_name CHARACTER VARYING; 
    tbl_name_parent CHARACTER VARYING := 'T_FM_HISTORYALARM'; 
    tbl_name_salve CHARACTER VARYING; 
    tbl_year INTEGER; 
    tbl_month INTEGER; 
    tbl_day INTEGER; 
    create_tbl_sql CHARACTER VARYING; 
    insert_tbl_sql CHARACTER VARYING; 
    index_sql CHARACTER VARYING; 
BEGIN 
    SELECT date_part('year',NEW.EVENTTIME) INTO tbl_year; 
    SELECT date_part('month',NEW.EVENTTIME) INTO tbl_month; 
    SELECT date_part('day',NEW.EVENTTIME) INTO tbl_day; 
    IF(tbl_month<10)THEN 
     tbl_name_salve=tbl_year||'0'||tbl_month; 
    ELSE 
     tbl_name_salve=tbl_year||tbl_month; 
    END IF; 
    IF(tbl_day<10)THEN 
     tbl_name_salve=tbl_name_salve||'0'||tbl_day; 
    ELSE 
     tbl_name_salve=tbl_name_salve||tbl_day; 
    END IF; 
    tbl_name=tbl_name_parent||'_'||tbl_name_salve; 

    --判断表 时间分段表是否存在 
    IF ((SELECT count(relname) FROM pg_class WHERE relname=tbl_name)>0) THEN 
     insert_tbl_sql='INSERT INTO '||tbl_name ||' VALUES(NEW.*)'; 
     EXECUTE insert_tbl_sql; 
    ELSE 
     create_tbl_sql='CREATE TABLE '||tbl_name 
     ||'(' 
     || 'CONSTRAINT '||tbl_name||'_EVENTTIME_CHECK'||' CHECK (EVENTTIME >= timestamp '''||tbl_name_salve||'000000''' ||' AND EVENTTIME < (timestamp '''||tbl_name_salve||'000000'' + interval ''1 day''))' 
     ||')INHERITS ('||tbl_name_parent||')'; 
     EXECUTE create_tbl_sql; 

     index_sql='CREATE INDEX '||tbl_name||'_EVENTTIME_INDEX ON '||tbl_name||'EVENTTIME'; 
     EXECUTE index_sql; 

     insert_tbl_sql='INSERT INTO '||tbl_name ||' VALUES(NEW.*)'; 
     EXECUTE insert_tbl_sql; 
    END IF; 
    RETURN NULL; 
END; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
,536,913 그것은 연료 소모량 및 트리거가 실행될 때 OK이지만

create trigger history_alarm_trigger before insert or update on t_fm_historyalarm for each row execute procedure history_alarm_partition(); 

값이 테이블 T_FM_HISTORYALARM 상위 테이블에 삽입 될 때, 에러가 occures : 63,210

트리거 코드를 생성한다.

내가 만들 테이블 statmenet 실행하면 : 그것은 잘 작동

CREATE TABLE T_FM_HISTORYALARM_20160101(CONSTRAINT T_FM_HISTORYALARM_20160101_eventtime_check CHECK (EVENTTIME >= timestamp '20160101000000' AND EVENTTIME < (timestamp '20160101000000' + interval '1 day')))INHERITS (T_FM_HISTORYALARM) 

합니다.

조언을 해 줄 수 있습니까? 대단히 감사합니다.

답변

1

이것은 예상되는 동작입니다. 포인트 8 참조)에 Greenplum Docs하십시오.

Triggers are not supported since they typically rely on the use of VOLATILE functions.

+0

카일, 고맙습니다. 그렇다면 어떻게 목표를 달성 할 수 있습니까? 테이블에 값을 삽입 할 때 테이블이 존재하지 않으면 테이블을 생성하고 싶습니다. –

+0

이벤트 시간은 현재 시간과 상관이 있습니까? 그렇다면 Greenplum 외부에서'cron'을 실행하여 데이터가 도착하기 전에 생성 된 새로운 데이터를위한 파티션을 항상 확보 할 수 있습니다. –

+0

좋아요,이 일을 할 계획입니다 다시 고마워요 –