PL / pgSQL执行vs执行

时间:2017-03-21 07:43:43

标签: postgresql plpgsql

执行和执行PL / pgSQL有什么区别?

从手册:

  

有时评估表达式或SELECT查询但丢弃结果很有用,例如在调用具有副作用但没有有用结果值的函数时。要在PL / pgSQL中执行此操作,请使用PERFORM语句。

但是,当我尝试这样的事情时:

perform 'create table foo as (select 1)';

什么都没发生。虽然这个查询应该有副作用(创建表),但结果可以被丢弃。

我认为我有一件事是正确的:为了运行函数,我可以使用perform:

perform pg_temp.addInheritance(foo);

3 个答案:

答案 0 :(得分:15)

PERFORM是用于调用void函数的plpgsql命令。 PLpgSQL对无用的SELECT语句很谨慎 - 不允许SELECT没有INTO子句。但有时你需要调用一个函数而你不需要存储结果(或函数没有任何结果)。使用SQL语句调用SELECT中的函数。但是在PLpgSQL中是不可能的 - 所以引入了命令PERFORM

CREATE OR REPLACE FUNCTION foo()
RETURNS void AS $$
BEGIN
  RAISE NOTICE 'Hello from void function';
END;
$$ LANGUAGE plpgsql;

-- direct call from SQL
SELECT foo();

-- in PLpgSQL
DO $$
BEGIN
  SELECT foo(); -- is not allowed
  PERFORM foo(); -- is ok
END;
$$;

PERFORM语句执行参数并忘记结果。

您的示例perform 'create table foo as (select 1)';

SELECT 'create table foo as (select 1)'相同。它返回一个字符串"创建表foo为(select 1)"并抛出此字符串。

EXECUTE语句计算表达式以获取字符串。在下一步中执行此字符串。

所以EXECUTE 'create table ' || some_var || '(a int)';有两个步骤

  1. 评估表达式'create table ' || some_var || '(a int)'
  2. 例如some_var是mytab,然后执行命令create table mytab(a int)
  3. 当赋值语句中未使用函数时,PERFORM语句用于函数调用。 EXECUTE用于评估动态SQL - 在运行时已知一种形式的SQL命令。

答案 1 :(得分:5)

docs you quote中的下一行:

  

执行查询并丢弃结果。 写相同的查询   您将编写SQL SELECT命令的方式,但替换初始   关键字SELECT with PERFORM。

强调我的

execute执行动态查询(上面的相同文档)

答案 2 :(得分:0)

我最近遇到一个案例,我需要为 DEFERRED 设置特定约束,并发现了一些有趣的东西。

 - EXECUTE 'SET CONSTRAINTS fk_a DEFERRED';
 - PERFORM 'SET CONSTRAINTS fk_a DEFERRED';

EXECUTEPERFORM 都没有错误地执行了语句,但只有 EXECUTE 为其余代码保留了操作。 不知何故,看起来 PERFORM 在它自己的事务 "bubble" 中运行。

就我而言,我有两个表 a 和 b 以及一个 FK(实际情况要复杂得多)。需要按父/子顺序插入数据,为此我们需要约束 DEFERRED。 使用 PERFORM 我们有外键违规,而 EXECUTE 我们没有。