Postgresql plpgsql:在动态插入到新创建的分区表中时插入错误

时间:2018-10-26 17:39:30

标签: postgresql plpgsql

我正在根据主表的日期列动态创建分区表。尝试将数据插入分区表时,将引发错误。下面是我正在使用的代码。感谢您的帮助。谢谢!

CREATE OR REPLACE FUNCTION "gracenote"."gn_tv_schedule_insert_trigger" ()  RETURNS trigger
  VOLATILE
AS $dbvis$
DECLARE
      partition_date TEXT;
      partitionn TEXT;
      partition_check TEXT;
      part_from DATE;
      part_to DATE;
      constrnt TEXT;
      indx TEXT;
      createStmts TEXT;
BEGIN
    partition_date := to_char(NEW.date,'YYYYMM');
    partition_check := 'gn_tv_schedule' || '_' || partition_date;
    partitionn := 'gracenote.gn_tv_schedule' || '_' || partition_date;
    part_from := DATE (TO_CHAR( NEW.date,'YYYY-MM') || '-01');
    part_to := DATE(TO_CHAR( NEW.date + INTERVAL '1 month', 'YYYY-MM' ) || '-01');
    constrnt := 'ck_' || to_char(NEW.date, 'YYYYMM');
    indx := 'idx_' || to_char(NEW.date, 'YYYYMM');

    IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition_check) THEN
                RAISE NOTICE 'A partition has been created %',partitionn;
                EXECUTE 'CREATE TABLE ' || partitionn || ' (check (date = ''' || NEW.date || ''')) INHERITS (gracenote.gn_tv_schedule);';

    END IF;

    IF ( NEW.date >= part_from AND
         NEW.date < part_to ) THEN
        createStmts := 'INSERT INTO '|| partitionn || ' VALUES (NEW.*);';
        --RAISE 'C - %', createStmts;
        EXECUTE createStmts;
    ELSE
        RAISE EXCEPTION 'Date out of range.  Fix the gn_tv_Schedule_insert_trigger() function!';
    END IF;

    RETURN NULL;
END;
$dbvis$ LANGUAGE plpgsql

错误:

[SELECT - 0 row(s), 0.000 secs]  [Error Code: 0, SQL State: 42P01]  ERROR: missing FROM-clause entry for table "new"
  Where: PL/pgSQL function gracenote.gn_tv_schedule_insert_trigger() line 38 at EXECUTE
SQL statement "INSERT INTO gracenote.gn_tv_schedule
    SELECT CAST(source_id AS BIGINT), CAST(prg_svc_id AS BIGINT), tms_id, CAST(date AS DATE), time, 
        cast(date||' '||time as timestamp) as start_time,
        cast(date||' '||time as timestamp)+cast(60*60*cast(substr(duration,3,2) as int)+60*cast(substr(duration,6,2) as int) as int)*interval '1 second' as end_time,
        duration, subtitled_lang, coalesce(CAST(subtitled_lang_flag AS BOOLEAN), 'false') subtitled_lang_flag, 
        dubbed_lang, coalesce(CAST(dubbed_lang_flag AS BOOLEAN), 'false') dubbed_lang_flag, tv_rating_body, tv_rating, tv_sub_rating_body, tv_sub_rating, 
        CAST(num_of_parts AS INTEGER), CAST(part_num AS INTEGER), net_syn_source, net_syn_type, quals, show_time, NOW()
   FROM gracenote.gn_tv_schedule_bkp_part 
   ORDER BY CAST(prg_svc_id AS BIGINT), CAST(date AS DATE), time"
PL/pgSQL function gracenote.fn_stg_mn_load_tv_schedule_panda() line 13 at SQL statement
Code: 0 SQL State: 00000 --- Executing Gracenote TV schedule
Code: 0 SQL State: 00000 --- A partition has been created gracenote.gn_tv_schedule_201811
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec  [0 successful, 0 warnings, 1 errors]

1 个答案:

答案 0 :(得分:0)

在Plpgsql中,EXECUTE在不同的范围内运行,您不会看到局部变量NEW。可以使用占位符$1USING子句动态传递它。

createStmts := 'INSERT INTO '|| partitionn || ' VALUES ($1.*);'  USING NEW;