PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgres pl/pgsql BŁĄD:kolumna nazwa_kolumny nie istnieje

Twoja funkcja może wyglądać tak:

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;

W PostgreSQL 9.1 lub później jest to prostsze z formatem format()

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

%I unika identyfikatorów, takich jak quote_ident() .

Główne punkty:

  • Wpadłeś na ograniczenie dynamicznego SQL, polegające na tym, że nie możesz używać parametrów dla identyfikatorów. Musisz zbudować ciąg zapytania z nazwą kolumny i następnie wykonaj go.

  • Możesz to zrobić z wartościami. Demonstruję użycie USING klauzula EXECUTE . Zwróć także uwagę na użycie quote_ident() :zapobiega wstrzykiwaniu SQL i pewnym błędom składni.

  • W dużym stopniu uprościłem też twoją funkcję. [RETURN QUERY EXECUTE][3] sprawia, że ​​Twój kod jest krótszy i szybszy. Nie ma potrzeby zapętlania się, jeśli wszystko, co robisz, to zwracanie wiersza.

  • Używam nazwy IN parametrów, dzięki czemu nie pomylisz się z notacją $ w ciągu zapytania. $1 i $2 wewnątrz ciągu zapytania odnieś się do wartości podanych w USING klauzuli, a nie do parametrów wejściowych.

  • Zmieniam na SELECT * ponieważ i tak musisz zwrócić cały wiersz, aby pasował do zadeklarowanego typu zwracanego.

  • Last but not least:pamiętaj, aby zastanowić się, co podręcznik ma do powiedzenia na temat funkcji zadeklarowanych SECURITY DEFINER .

TYP ZWROTU

Jeśli nie chcesz zwracać całego wiersza, jedną dogodną możliwością jest:

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

Wtedy nie musisz dostarczać listy definicji kolumn przy każdym wywołaniu i możesz uprościć:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak usunąć powrót karetki i nowe linie w Postgresql?

  2. Skalowanie połączeń w PostgreSQL przy użyciu puli połączeń

  3. Postgres:Jak sformatować znacznik czasu int jako czytelny ciąg daty?

  4. Postgres nie działa z „nie można otworzyć pliku mapowania relacji global/pg_filenode.map”

  5. Jak porównać dwa schematy w PostgreSQL