T
Маусым 7, 2023, 9:12 Т.Қ.

Ошибка при выполнении триггерной функции (GreenPlum)

PgSQL, GreenPlum, Триггерные функции

Есть 3 таблицы fact_amount со структурой:

  1. CREATE TABLE fact_amount (
  2. id serial4 NOT NULL,
  3. fdate date NULL,
  4. type_activity_id int4 NULL,
  5. status_id int4 NULL,
  6. CONSTRAINT fact_amount_pk_1 PRIMARY KEY (id),
  7. CONSTRAINT fact_amount_fk_1 FOREIGN KEY (category_id) REFERENCES mdv_db.spr_category(category_id),
  8. CONSTRAINT fact_amount_fk_2 FOREIGN KEY (status_id) REFERENCES mdv_db.spr_status(status_id),
  9. CONSTRAINT fact_amount_fk_3 FOREIGN KEY (type_activity_id) REFERENCES mdv_db.spr_type_activity(type_activity_id)
  10. );

spr_status:

  1. CREATE TABLE spr_status (
  2. status_id serial4 NOT NULL,
  3. status_name varchar NULL,
  4. CONSTRAINT spr_status_pk PRIMARY KEY (status_id)
  5. );

spr_type_activity:

  1. CREATE TABLE spr_type_activity (
  2. type_activity_id serial4 NOT NULL,
  3. type_activity_name varchar NULL,
  4. CONSTRAINT spr_type_activity_pk PRIMARY KEY (type_activity_id)
  5. );

Надо создать представление с данными из таблицы fact_amount и транспонированной spr_type_activity и значениями из spr_status. Сначала создал функцию, которая все это преобразовывала. Все прекрасно работало, кроме того, чтобы при изменении в справочнике обновлялось представление. В итоге преобразовал ее в триггерную фушкцию:

  1. CREATE TRIGGER tr_spr_type_activity
  2. AFTER INSERT OR DELETE OR UPDATE
  3. ON spr_type_activity FOR EACH ROW EXECUTE PROCEDURE c_crosstab();
  4.  
  1. CREATE OR REPLACE FUNCTION c_crosstab()
  2. RETURNS trigger
  3. LANGUAGE plpgsql
  4. AS $function$
  5. DECLARE
  6. casesql varchar;
  7. dynsql varchar;
  8. r record;
  9. eavsql_inarg varchar;
  10. resview varchar;
  11. rowid varchar;
  12. colid varchar;
  13. val varchar;
  14. BEGIN
  15. eavsql_inarg = 'SELECT fa.id,
  16. sb.id_branch,
  17. sb.parent_branch_id,
  18. fa.fdate,
  19. sb.branch_name,
  20. ss.status_name,
  21. fa.type_activity_id,
  22. sa.type_activity_name
  23. FROM mdv_db.fact_amount fa
  24. LEFT JOIN mdv_db.branch sb ON fa.id_branch = sb.id_branch
  25. LEFT JOIN mdv_db.spr_category sc ON fa.category_id = sc.category_id
  26. LEFT JOIN mdv_db.spr_status ss ON fa.status_id = ss.status_id
  27. LEFT JOIN mdv_db.spr_type_activity sa ON fa.type_activity_id = sa.type_activity_id';
  28. resview = 'v_crosstab';
  29. rowid = 'id';
  30. colid = 'type_activity_name';
  31. val = 'status_name';
  32. dynsql = '';
  33.  
  34. FOR r IN SELECT * FROM pg_views
  35. WHERE lower(viewname) = lower(resview)
  36. LOOP
  37. EXECUTE 'DROP VIEW IF EXISTS ' || resview;
  38. END LOOP;
  39.  
  40. casesql = 'SELECT DISTINCT ' || colid || ' AS v from (' || eavsql_inarg || ') eav ORDER BY ' || colid;
  41.  
  42. FOR r IN EXECUTE casesql LOOP
  43. dynsql = dynsql || ', ' || 'CASE WHEN ' || colid || '=''' || r.v || ''' THEN ' || val || ' ELSE NULL END AS ' || r.v;
  44. END LOOP;
  45.  
  46. dynsql = 'CREATE VIEW ' || resview || ' AS SELECT ' || rowid || dynsql || ' from (' || eavsql_inarg || ') eav ORDER BY ' || rowid;
  47.  
  48. RAISE NOTICE 'dynsql %1', dynsql;
  49.  
  50. EXECUTE dynsql;
  51. END;
  52. $function$

Выходит следующая ошибка:

  1. Error synchronizing data with database
  2.  
  3. Причина:
  4. SQL Error [0A000]: ERROR: function cannot execute on a QE slice because it issues a non-SELECT statement (seg5 172.23.133.194:6002 pid=32075)
  5. Где: SQL statement "DROP VIEW IF EXISTS v_crosstab"
  6. PL/pgSQL function c_crosstab() line 34 at EXECUTE statement

Созданием процедур/функций раньше не занимался. В чем ошибка и как ее исправить?

1

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

0

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз