sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL-fejl:forespørgselsstrengargumentet for EXECUTE er null

Fejlmeddelelsen er

Du har to EXECUTE kommandoer:

_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;

Den eneste del, der kan være NULL er table_name .
Den eneste chance for table_name for at blive NULL er her:

SELECT raised_local_time FROM notifications WHERE id=_notification_id
INTO _raised_local_time;

Så årsagen skal være en af ​​to årsager :

  1. NEW.notification_id er NULL .

  2. Der er ingen række i notifications for den givne NEW.notification_id .

Prøv denne modificerede triggerfunktion til fejlretning :
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;
  • Fjern ubrugte variabler og forenkle koden. (Dette er naturligvis et forenklet eksempel.)

    • Blandt andet behøver du ikke date_trunc() overhovedet. Du skal blot føre det originale tidsstempel til to_char() .

    • Det giver ingen mening at bruge varchar(n) . Brug blot text eller varchar .

    • Undgå for mange opgaver, hvor unødvendige - forholdsvis dyre i PL/pgSQL.

  • Tilføj en RAISE for at tjekke min hypotese.
    Hvis du får fejlmeddelelsen, ville det være næste skridt at skelne mellem de to mulige årsager. Bør være trivielt ...




  1. UNIK begrænsning vs kontrol før INSERT

  2. Oprettelse af MySQL-udløsere ved hjælp af DataMapper

  3. Hvad er forskellen mellem tinyint, smallint, mediumint, bigint og int i MySQL?

  4. Sørg for, at php-session får den samme oracle-session, når du bruger oci_pconnect