9

出于迁移目的,我正在比较 PostgreSQL 与 SQLServer。现在我正在评估 T-SQL 与 PL/pgSQL,问题是在 T-SQL 中您可以使用循环或声明变量,例如:

declare @counter int
set @counter = 0
while @counter < 10
begin
   set @counter = @counter + 1
   print 'The counter is ' + cast(@counter as char)
end

无需将其放在函数或过程中。我可以在 PostgreSQL 中这样做吗?

在网上搜索,我在 MySQL 中发现了一个否定的答案,但我没有找到 Postgres 的这样的答案。

4

2 回答 2

26

不能 DECLARE(全局)变量(有解决方法)不能使用普通 SQL 循环 - @bma 提供的递归 CTE 除外(严格来说,它实际上是迭代行,而不是循环)。

但是,有这样的临时程序代码的DO声明。与 Postgres 9.0 一起引入。它像一次性函数一样工作,但不接受任何参数,也不返回任何内容。您可以RAISE注意到等,因此您的示例可以正常工作:

DO
$do$
DECLARE
   _counter int := 0;
BEGIN
   WHILE _counter < 10
   LOOP
      _counter := _counter + 1;
      RAISE NOTICE 'The counter is %', _counter;  -- coerced to text automatically
   END LOOP;
END
$do$

如果没有另外指定,正文中的语言默认为plpgsql. 但是,如果您声明它,您可以使用任何已注册的程序语言LANGUAGE plpython(例如:) 。

Postgres 还提供generate_series()临时生成集合,这在许多情况下可以避免循环的需要。尝试在 SO 上搜索示例。

此外,您可以在纯 SQL 中的数据修改 CTEWHERE中使用该子句来分叉案例并模拟...IF .. THEN .. ELSE .. END

于 2013-08-20T17:34:15.523 回答
3

假设您使用的是 Postgresql 8.4+,您可以使用 WITH RECURSIVE 递归查询结果集。文档:http ://www.postgresql.org/docs/current/static/queries-with.html

这将允许您循环您的集合并以各种方式处理数据。

于 2013-08-20T17:13:06.157 回答