如何在不创建函数的情况下执行 pl/pgsql 代码?

63

在SQL Server中,我可以通过SQL Server Management Studio或任何其他客户端执行带有完整过程逻辑的即席T-SQL代码。我已经开始使用PostgreSQL并遇到了一些差异,因为PGSQL要求任何逻辑都必须嵌入函数中。

有没有一种方法可以在不创建和执行函数的情况下执行PL/PGSQL代码?

3个回答

83
Postgres 9
DO $$ 
-- declare
BEGIN
  /* pl/pgsql here */
END $$;

4
对于任何找到这个答案并尝试过却得到“ERROR: syntax error at or near 'SELECT'”的人,你需要加上BEGIN和END。 DO $$ BEGIN /* 在此处放置pl/pgsql代码 */ END $$ - Greg Najda
4
但是这段代码如何返回查询结果?如果我在pl/pgsql部分中放一个SELECT语句,我会得到 ERROR: query has no destination for result data 的错误提示。 - isapir
3
@Igal:不行。你无法从DO语句中返回任何内容。你可以通过引发通知、写入临时表或打开游标等可能的解决方法来实现。 - Erwin Brandstetter
当我使用$$DECLARE而不是$$时,只需要做一点小的更改工作。
DO $$DECLARE srno integer; BEGIN select into srno count(reg_count) from table_name where condition; raise notice 'Desired Count %', srno; END $$;
- Er. Amit Joshi
我很高兴看到这个与EF Core迁移一起工作。 - jenson-button-event

6

不,目前还没有。版本9.0(仍处于Alpha测试阶段)将具备此选项(do),你必须等待其发布。


+1,但我认为它是针对8.5版本发布的- http://developer.postgresql.org/pgdocs/postgres/release-8.5.html - Michael Krelin - hacker
1
我认为8.5变成9.0是因为实施了一些重要的功能... - anon
是的,8.5变成了9.0。DO很好用,只需下载alpha版本并开始测试:http://www.postgresql.org/download/snapshots - Frank Heikens
弗兰克,希望我知道在哪里下载“时间”来玩9.0的;-) - Michael Krelin - hacker
现在9.6.0有文档吗? - TangMonk
@TangMonk DO v9.6文档:https://www.postgresql.org/docs/9.6/static/sql-do.html - Davos

1

我曾经为了让它正常工作而苦苦挣扎,因为它对于在恰当的位置添加分号非常严格。但是一旦你习惯了这一点,它就能很好地工作。当然,除了无法返回记录之外,你还可以提出通知和异常,并使用像@ErwinBrandstetter在上面的评论中指出的临时表等其他解决方法。

e.g.:

DO 
$$
BEGIN
  IF EXISTS(SELECT 'any rows?' 
              FROM {your_table} 
              WHERE {your_column} = 'blah')
  THEN
      RAISE NOTICE 'record exists';
  ELSE
      RAISE EXCEPTION 'record does not exist';
  END IF;

  DROP TABLE IF EXISTS foo;

  CREATE TEMP TABLE foo AS
  SELECT 'bar'::character varying(5) as baz;
END 
$$;

SELECT * FROM foo;

我认为类似于SQL Server/Oracle存储过程的返回行的能力将在下一个版本的PostgreSQL中推出。为什么这么长时间才推出,我无法理解。 - anon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接