sql >> Database >  >> RDS >> PostgreSQL

Postgres pl/pgsql ERROR:kolom kolomnaam bestaat niet

Uw functie kan er als volgt uitzien:

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;

IN PostgreSQL 9.1 of later is dat eenvoudiger met format()

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

%I ontsnapt aan identifiers zoals quote_ident() .

Belangrijkste punten:

  • U liep tegen de beperking van dynamische SQL aan dat u geen parameters voor id's kunt gebruiken. U moet de queryreeks bouwen met de kolomnaam en vervolgens voer het uit.

  • Dat kun je wel doen met waarden. Ik demonstreer het gebruik van de USING clausule voor EXECUTE . Let ook op het gebruik van quote_ident() :voorkomt SQL-injectie en bepaalde syntaxisfouten.

  • Ik heb je functie ook grotendeels vereenvoudigd. [RETURN QUERY EXECUTE][3] maakt je code korter en sneller. U hoeft niet te herhalen als u alleen de rij terugstuurt.

  • Ik gebruik de naam IN parameters, zodat u niet in de war raakt met de $-notatie in de queryreeks. $1 en $2 verwijzen in de queryreeks naar de waarden in de USING clausule, niet naar de invoerparameters.

  • Ik verander naar SELECT * omdat je toch de hele rij moet retourneren om overeen te komen met het opgegeven retourtype.

  • Last but not least:denk goed na wat de handleiding te zeggen heeft over functies die zijn gedeclareerd SECURITY DEFINER .

RETOURTYPE

Als u niet de hele rij wilt retourneren, is een handige mogelijkheid:

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

Dan hoeft u niet bij elke oproep een kolomdefinitielijst te verstrekken en kunt u vereenvoudigen tot:

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



  1. SQL-query om de lijst met supervisorhiërarchie te krijgen. werknemer --> supervisor --> supervisor

  2. Hoe converteer ik een string tot nu toe in MySQL?

  3. Ruby CSV leest velden met meerdere regels

  4. Postgres retourneert [null] in plaats van [] voor array_agg van join-tabel