sql >> Databáze >  >> RDS >> PostgreSQL

Postgres pl/pgsql CHYBA:sloupec název_sloupce neexistuje

Vaše funkce může vypadat takto:

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;

V PostgreSQL 9.1 nebo později je to jednodušší s formátem format()

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

%I escapuje identifikátory jako quote_ident() .

Hlavní body:

  • Naráželi jste na omezení dynamického SQL, že nemůžete použít parametry pro identifikátory. Musíte vytvořit řetězec dotazu s názvem sloupce a pak provést.

  • Můžete to udělat s hodnotami. Ukazuji použití USING klauzule pro EXECUTE . Všimněte si také použití quote_ident() :zabraňuje vkládání SQL a určitým syntaktickým chybám.

  • Také jsem značně zjednodušil vaši funkci. [RETURN QUERY EXECUTE][3] zkrátí a zrychlí váš kód. Není třeba opakovat, pokud vše, co uděláte, je vrátit řádek.

  • Používám s názvem IN parametry, abyste se nepletli s $-notací v řetězci dotazu. $1 a $2 uvnitř řetězce dotazu odkazují na hodnoty uvedené v USING klauzule, nikoli vstupním parametrům.

  • Změním na SELECT * protože stejně musíte vrátit celý řádek, aby odpovídal deklarovanému typu návratu.

  • V neposlední řadě:Nezapomeňte zvážit, co příručka říká o funkcích deklarovaných SECURITY DEFINER .

TYP VRÁCENÍ

Pokud nechcete vrátit celý řádek, jedna pohodlná možnost je:

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

Pak nemusíte při každém volání poskytovat seznam definic sloupců a můžete to zjednodušit na:

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



  1. MySQL nahradí všechny mezery za -

  2. Měl bych používat PreparedStatements pro všechny vložky databáze v Javě?

  3. Foreach smyčka MySQL

  4. Jaká je jednotka času v protokolu pomalého dotazování MySQL?