PostgreSQL表变量

37

在T-SQL中是否有类似于表变量的东西?
在SqlServer中,它看起来是这样的:

DECLARE @ProductTotals TABLE
(
  ProductID int,
  Revenue money
)

那么在程序中,我可以:

INSERT INTO @ProductTotals (ProductID, Revenue)
  SELECT ProductID, SUM(UnitPrice * Quantity)
  FROM [Order Details]
  GROUP BY ProductID

并像普通表格一样操作此变量。

这是一个描述:http://odetocode.com/Articles/365.aspx


如果我没记错的话,你不能将变量声明为TABLE,在postgresql中没有类型TABLE。 - cojack
3
表变量的功能与临时表相同。只是该文章声称,表变量在 SQL Server 中的性能最佳。 - Clodoaldo Neto
1
@ClodoaldoNeto 在 SQL Server 中,有两种选项可用于此用例:第一种是像在 Postgres 中一样使用临时表,第二种是使用表变量。根据情况,每种方法都有其优点。 - Rob_vH
2个回答

44

在PostgreSQL中使用临时表。对于你的示例:

CREATE TEMP TABLE product_totals (
   product_id int
 , revenue money
);

关于 CREATE TABLE 的手册:

如果指定,表将被创建为临时表。临时表会在会话结束时自动删除,或者可选择在当前事务结束时删除(参见下面的 ON COMMIT)。默认的 search_path 首先包含临时模式,因此只要存在临时表,就不会选择相同名称的永久性现有表作为新计划,除非使用模式限定名称引用它们。在临时表上创建的任何索引也会自动成为临时的。

Postgres 9.1 或更高版本中的未记录日志表是一个相关的功能。通过不写入WAL,可以节省磁盘写入。这是 Robert Haas 的 讨论:

另外,关于 money 数据类型:


1
在PostgreSQL 9.4中,如果同时调用函数的用户使用了临时表,我可以安全地假设为每个用户创建一个新的临时表实例吗? - Diligent Key Presser
4
临时表只在相同的数据库会话中可见,并且在会话结束时被删除。这适用于Postgres的任何版本。即使对于同一数据库用户在多次连接(多个会话)时也可以有不同的临时表。在内部,每个会话使用一个单独的临时模式。 - Erwin Brandstetter
2
这个帖子表明,pg数组可能是T-SQL内存表的等效形式,并且临时表可能会引入大量额外的开销。 - dleavitt
如果连接到数据库是只读的,那么这样做行不通。 - Qwertiy

8
你可以使用一个复合类型的数组来代替。
CREATE TABLE xx(a int, b int);

CREATE OR REPLACE FUNCTION bubu()
RETURNS void AS $$
DECLARE _x xx[];
BEGIN
   _x := ARRAY(SELECT xx FROM xx);
   RAISE NOTICE '_x=%', _x;
   ...

2
确实不行: CREATE TABLE xx(a int, b int); insert into xx values(1,2); insert into xx values(3,4); DO $$DECLARE _x xx[]; BEGIN _x := ARRAY(SELECT * FROM xx); RAISE DEBUG '_x is %',_x; END$$; code`[2016-04-05 21:47:45] 解析 <unnamed>: DO $$DECLARE _x xx[]; BEGIN _x := ARRAY(SELECT * FROM xx); RAISE DEBUG '_x is %',_x; END$$ [2016-04-05 21:47:45] 绑定 <unnamed> 到 <unnamed> [2016-04-05 21:47:45] [42601] 错误: 子查询必须只返回一列 在: PL/pgSQL function inline_code_block line 3 at assignment` - uudecode

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