PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Грешка в PostgreSQL:аргументът на низа на заявката на EXECUTE е нула

Съобщението за грешка е

Имате две EXECUTE команди:

_query := 'CREATE TABLE public.'
        || quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
EXECUTE _query;

...

EXECUTE 'INSERT INTO public.'
      || quote_ident(_table_name) || ' VALUES ($1.*)' USING NEW;

Единствената част, която може да бъде NULL е table_name .
Единственият шанс за table_name да стане NULL е тук:

SELECT raised_local_time FROM notifications WHERE id=_notification_id
INTO _raised_local_time;

Така че причината трябва да е една от двете причини :

  1. NEW.notification_id е NULL .

  2. Няма ред в notifications за дадения NEW.notification_id .

Опитайте тази модифицирана тригерна функция за отстраняване на грешки :
CREATE OR REPLACE FUNCTION partition_evidence_by_month()
  RETURNS trigger AS
$func$
DECLARE 
   _table_name text;
BEGIN
   SELECT 'evidence-' || to_char(raised_local_time, 'YYYY-MM')
   FROM   public.notifications -- schema-qualify to be sure
   WHERE  id = NEW.notification_id
   INTO   _table_name;

   IF _table_name IS NULL THEN
      RAISE EXCEPTION '_table_name is NULL. Should not occur!';
   END IF;

   IF NOT EXISTS (   -- create table if it does not exist
      SELECT 1
      FROM   pg_catalog.pg_class c
      JOIN   pg_catalog.pg_namespace n ON n.oid = c.relnamespace
      WHERE  c.relkind = 'r'
      AND    c.relname = _table_name
      AND    n.nspname = 'public') THEN

      EXECUTE 'CREATE TABLE public.'
            || quote_ident(_table_name) || ' ( ) INHERITS (public.evidence)';
   END IF;

   EXECUTE 'INSERT INTO public.'
         || quote_ident(_table_name) || ' VALUES $1'  -- Use NEW row directly
   USING  NEW;       -- write data to the partition table

   RETURN NULL;
END
$func$ LANGUAGE plpgsql;
  • Премахнете неизползваните променливи и опростете кода. (Това очевидно е опростен пример.)

    • Освен всичко друго, нямате нужда от date_trunc() изобщо. Просто подайте оригиналното времево клеймо на to_char() .

    • Няма смисъл да използвате varchar(n) . Просто използвайте text или varchar .

    • Избягвайте твърде много присвоявания, когато не е необходимо - сравнително скъпо в PL/pgSQL.

  • Добавете RAISE за да проверя моята хипотеза.
    Ако получите съобщение за грешка, следващата стъпка ще бъде разграничаването на двете възможни причини. Трябва да е тривиално...




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изтрийте с помощта на CTE по-бавно, отколкото с помощта на временна таблица в Postgres

  2. Кеш на план за изпълнение за PL/pgSQL функции в PostgreSQL

  3. Как да се свържете с postgresql от ios9

  4. Postgres:ИЗБЕРЕТЕ име на колона въз основа на булева стойност

  5. разлика между localhost и postgres за хост в docker