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

Име на таблица като параметър на функцията на PostgreSQL

Това може да бъде допълнително опростено и подобрено:

CREATE OR REPLACE FUNCTION some_f(_tbl regclass, OUT result integer)
    LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format('SELECT (EXISTS (SELECT FROM %s WHERE id = 1))::int', _tbl)
   INTO result;
END
$func$;

Обадете се с име, квалифицирано по схема (вижте по-долу):

SELECT some_f('myschema.mytable');  -- would fail with quote_ident()

Или:

SELECT some_f('"my very uncommon table name"');

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

Използвайте OUT параметъра за опростяване на функцията. Можете директно да изберете резултата от динамичния SQL в него и готово. Няма нужда от допълнителни променливи и код.

EXISTS прави точно това, което искате. Получавате true ако редът съществува или false в противен случай. Има различни начини да направите това, EXISTS обикновено е най-ефективен.

Изглежда искате цяло число назад, така че прехвърлям boolean резултат от EXISTS към integer , което дава точно това, което сте имали. Бих върнал boolean вместо това.

Използвам идентификатора на обекта тип regclass като входен тип за _tbl . Това прави всичко quote_ident(_tbl) или format('%I', _tbl) ще стане, но по-добре, защото:

  • .. предотвратява SQL инжектиране също толкова добре.

  • .. се проваля незабавно и по-изящно, ако името на таблицата е невалидно / не съществува / е невидимо за текущия потребител. (regclass параметърът е приложим само за съществуващ таблици.)

  • .. работи с квалифицирани по схема имена на таблици, където обикновен quote_ident(_tbl) или format(%I) биха се провалили, защото не могат да разрешат неяснотата. Ще трябва да предавате и избягвате имената на схеми и таблици отделно.

Работи само за съществуващи таблици, очевидно.

Все още използвам format() , защото опростява синтаксиса (и за да демонстрира как се използва), но с %s вместо %I . Обикновено заявките са по-сложни, така че format() помага повече. За простия пример бихме могли просто да конкатенираме:

EXECUTE 'SELECT (EXISTS (SELECT FROM ' || _tbl || ' WHERE id = 1))::int'

Не е необходимо да се квалифицира в таблица id колона, докато има само една таблица в FROM списък. В този пример не е възможна неяснота. (Динамични) SQL команди в EXECUTE иматотделен обхват , функционалните променливи или параметри не се виждат там - за разлика от обикновените SQL команди в тялото на функцията.

Ето защо винаги избягвайте правилно въвеждането на потребителя за динамичен SQL:

db<>цигулка тук демонстриране на SQL инжекция
Стар sqlfiddle



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Условен оператор INSERT INTO в postgres

  2. Нулиране на брояча за автоматично увеличение в postgres

  3. трябва ли да активирам обединяването на изрази c3p0?

  4. Как да зададете стойност на полето за съставна променлива с помощта на динамичен SQL

  5. Изберете Номер на ред в postgres