Выполнение запроса в Postgresql - PullRequest
0 голосов
/ 26 июня 2019

Как выполнить запрос в функции format() в Postgres? Может ли кто-нибудь, пожалуйста, ведите меня.

IF NOT EXISTS ( SELECT  format ('select id 
         from '||some_table||' where emp_id 
             ='||QUOTE_LITERAL(m_emp_id)||' ) 
              ) ;

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Вы можете объединить EXECUTE FORMAT и условие IF, используя GET DIAGNOSTICS

Вот пример, который вы можете использовать повторно с минимальными изменениями. Я передал имя таблицы, используя идентификатор %I и параметризованный аргумент ($1) для employee_id.Это безопасно для SQL-инъекций. LIMIT 1 используется, так как нас интересует, существует ли хотя бы одна строка.Это повысит производительность запросов и будет эквивалентно (или эффективно) использованию EXISTS для огромных наборов данных с несколькими совпадающими строками.

DO $$
DECLARE
some_table TEXT := 'employees';
m_emp_id    INT := 100;
cnt         INT;
BEGIN

 EXECUTE  format ('select 1 
                    from %I where employee_id 
                        = $1 LIMIT 1',some_table  ) USING m_emp_id ;

GET DIAGNOSTICS cnt = ROW_COUNT;

IF cnt > 0
THEN
     RAISE NOTICE 'FOUND';
ELSE
     RAISE NOTICE 'NOT FOUND';
END IF;

END 
$$; 

Результат

NOTICE:  FOUND
DO
0 голосов
/ 26 июня 2019

Ответ @Kaushik Nayak является правильным - я постараюсь немного подробнее объяснить эту проблему.

PLpgSQL знает два типа запросов к базе данных:

  • статические(встроенный) SQL - SQL записывается непосредственно в код plpgsql.Статический SQL можно параметризовать (можно использовать переменную), но параметры следует использовать в качестве идентификатора таблицы или столбца.Семантика (и план выполнения) должны быть одинаковыми каждый раз.

  • динамический SQL - этот стиль запросов похож на классический клиентский SQL - SQL записывается как строковое выражение (которое оценивается) во время выполнения, и результат этого строкового выражения оценивается как запрос SQL.Ограничений для параметризации не существует, но существует риск внедрения SQL-кода (параметры должны быть очищены от SQL-внедрения (хорошие примеры - в ответе @Kaushik Nayak)).Более того, при каждой перепланировке возникают издержки, поэтому динамический SQL следует использовать только тогда, когда это необходимо.Динамический SQL обрабатывается командой EXECUTE.Синтаксис команд IF:

    IF expression THEN
      statements; ...
    END IF;
    

Нельзя помещать в выражения PLpgSQL-выражения.Таким образом, эта задача должна быть разделена на несколько шагов:

EXECUTE format(...) USING m_emp_id;
GET DIAGNOSTICS rc = ROW_COUNT;
IF cnt > 0 THEN
  ...
END IF;
...