Postgresql中的查询执行

时间:2019-06-26 06:56:26

标签: postgresql plpgsql dynamic-sql

如何在Postgres的format()函数中执行查询?谁能指导我。

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

2 个答案:

答案 0 :(得分:1)

您可以使用EXECUTE FORMAT来组合IFGET 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

答案 1 :(得分:0)

@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;