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

Postgres pl/pgsql FEJL:kolonne kolonnenavn eksisterer ikke

Din funktion kunne se sådan ud:

CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)    
  RETURNS SETOF transactions AS   
$BODY$   
BEGIN

RETURN QUERY EXECUTE '
   SELECT *
   FROM   transactions
   WHERE  ' || quote_ident(_col) || ' = $1
   LIMIT  $2'
USING _val, _limit;

END;   
$BODY$  
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

I PostgreSQL 9.1 eller senere, det er enklere med format()

...
RETURN QUERY EXECUTE format('
   SELECT *
   FROM   transactions
   WHERE  %I = $1
   LIMIT  $2', _col)
USING _val, _limit;
...

%I undslipper identifikatorer som quote_ident() .

Vigtige punkter:

  • Du stødte ind i begrænsningen af ​​dynamisk SQL, at du ikke kan bruge parametre til identifikatorer. Du skal bygge forespørgselsstrengen med kolonnenavnet og derefter udføre det.

  • Du kan dog gøre det med værdier. Jeg demonstrerer brugen af ​​USING klausul for EXECUTE . Bemærk også brugen af ​​quote_ident() :forhindrer SQL-injektion og visse syntaksfejl.

  • Jeg har også stort set forenklet din funktion. [RETURN QUERY EXECUTE][3] gør din kode kortere og hurtigere. Du behøver ikke at gå i løkke, hvis alt du gør er at returnere rækken.

  • Jeg bruger navnet IN parametre, så du ikke bliver forvekslet med $-notationen i forespørgselsstrengen. $1 og $2 inde i forespørgselsstrengen henvises til værdierne i USING klausul, ikke til inputparametrene.

  • Jeg skifter til SELECT * da du alligevel skal returnere hele rækken for at matche den deklarerede returtype.

  • Sidst men ikke mindst:Sørg for at overveje, hvad manualen har at sige om funktioner, der er erklæret SECURITY DEFINER .

RETURNERINGSTYPE

Hvis du ikke ønsker at returnere hele rækken, er en praktisk mulighed:

CREATE FUNCTION select_transactions3(_col text, _val text, _limit int)    
  RETURNS TABLE (invoice_no varchar(125), amount numeric(12,2) AS ...

Så behøver du ikke at angive en kolonnedefinitionsliste med hvert opkald og kan forenkle til:

SELECT * FROM select_to_transactions3('invoice_no', '1103300105472', 1);



  1. Hvordan bruger man session inde på websider?

  2. Overførsel af en række data som inputparameter til en Oracle-procedure

  3. Hvordan bruger man OUTPUT til at fange nyt og gammelt ID?

  4. PostgreSQL Connection Pooling:Del 4 – PgBouncer vs. Pgpool-II