PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

ГРЕШКА на Postgres pl/pgsql:колона име_на_колона не съществува

Вашата функция може да изглежда така:

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;

В PostgreSQL 9.1 или по-късно, което е по-лесно с format()

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

%I избягва идентификатори като quote_ident() .

Основни точки:

  • Натъквахте се на ограничението на динамичния SQL, че не можете да използвате параметри за идентификатори. Трябва да създадете низа на заявката с името на колоната и след това изпълнете го.

  • Можете обаче да направите това със стойности. Демонстрирам използването на USING клауза за EXECUTE . Също така обърнете внимание на използването на quote_ident() :предотвратява SQL инжектиране и определени синтактични грешки.

  • Също така до голяма степен опростих вашата функция. [RETURN QUERY EXECUTE][3] прави вашия код по-кратък и по-бърз. Няма нужда да правите цикъл, ако всичко, което правите, е да върнете реда.

  • Използвам named IN параметри, така че да не се объркате с $-нотацията в низа на заявката. $1 и $2 вътре в низа на заявката се обърнете към стойностите, предоставени в USING клауза, а не към входните параметри.

  • Променям на SELECT * тъй като така или иначе трябва да върнете целия ред, за да съответства на декларирания тип връщане.

  • Последно, но не на последно място:Не забравяйте да вземете под внимание какво казва ръководството относно функциите, декларирани SECURITY DEFINER .

ВРЪЩАН ТИП

Ако не искате да върнете целия ред, една удобна възможност е:

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

Тогава не е нужно да предоставяте списък с дефиниции на колони с всяко извикване и можете да опростите до:

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. Настройване на Django с поддръжка на GeoDjango в AWS Beanstalk или EC2 инстанция

  2. Има ли нещо като функция zip() в PostgreSQL, която комбинира два масива?

  3. Заявките се забиват в PG::Connection#async_exec

  4. Когато автовакуумът не вакуумира

  5. Актуализирайте таблица и покажете актуализирани редове с една SQL команда