【发布时间】:2015-11-16 20:25:30
【问题描述】:
在 PostgreSQL 中,ROW() 函数是做什么用的?
具体有什么区别
SELECT ROW(t.f1, t.f2, 42) FROM t;
其中f1 的类型为int,f2 的类型为text
和
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
【问题讨论】:
标签: sql postgresql types row
在 PostgreSQL 中,ROW() 函数是做什么用的?
具体有什么区别
SELECT ROW(t.f1, t.f2, 42) FROM t;
其中f1 的类型为int,f2 的类型为text
和
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
【问题讨论】:
标签: sql postgresql types row
您混淆了抽象级别。正如其他答案已经指出的那样,CREATE TYPE 仅在系统中注册(复合/行)类型。而ROW 构造函数实际上返回一行。
使用ROW 构造函数创建的行类型不保留列名,当您尝试将行转换为 JSON 时,这一点会很明显。
ROW 在大多数时候只是一个干扰词。 The documentation:
当列表中有多个表达式时,关键字
ROW是可选的。
演示:
SELECT t AS r1, row_to_json(t) AS j1
, ROW(1, 'x', NUMERIC '42.1') AS r2, row_to_json(ROW(1, 'x', NUMERIC '42.1')) AS j2
, (1, 'x', NUMERIC '42.1') AS r3, row_to_json( (1, 'x', NUMERIC '42.1')) AS j3
, (1, 'x', '42.1')::myrowtype AS r4, row_to_json((1, 'x', '42.1')::myrowtype) AS j4
FROM (SELECT 1, 'x', NUMERIC '42.1') t;
r1 和 j1 保留原始列名。r2 和 j2 不这样做。r3 和 j3 相同;来演示ROW 只是噪音。r4 和j4 携带注册类型的列名。
如果元素的 number 和 data types 匹配行类型 - names,您可以将行(记录)转换为已注册的行类型> 的输入字段被忽略。
【讨论】:
你问的是 value 和 type 之间的区别。
这与 OO 语言中的对象和类之间的区别大致相同。
在第一种情况下,您正在构建一个可用于比较、行写入或传递给接受复合参数的函数的值。
在第二种情况下,您定义的类型可用于例如函数或表定义中。
【讨论】:
行构造函数可用于构建复合值以存储在复合类型的表列中,或传递给接受复合参数的函数。 此外,还可以比较两个行值或用 IS NULL 或 IS NOT NULL 测试行。
例子:
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
CREATE TABLE mytable (ct myrowtype);
INSERT INTO mytable(ct) VALUES (CAST(ROW(11,'this is a test',2.5) AS myrowtype));
【讨论】:
ROW(...) 不是函数。它是 SQL 语法,更像ARRAY[...] 构造函数而不是函数。
ROW 构造函数主要用于形成匿名记录。当您需要将一组字段保存在一起但它们不对应于现有的表类型或复合数据类型时,这可能很有用。
这两个在 PostgreSQL 中是等价的:
test=> SELECT t FROM (SELECT 1, 'x', NUMERIC '42.1') AS t;
t
------------
(1,x,42.1)
(1 row)
test=> SELECT ROW(1, 'x', NUMERIC '42.1');
row
------------
(1,x,42.1)
(1 row)
两者都创建匿名记录:
test=> SELECT pg_typeof(t) FROM (SELECT 1, 'x', NUMERIC '42.1') AS t;
pg_typeof
-----------
record
(1 row)
test=> SELECT pg_typeof(ROW(1, 'x', NUMERIC '42.1'));
pg_typeof
-----------
record
(1 row)
ROW 创建的记录可以对应于现有类型,当您将复合类型传递给函数时,例如给定:
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
您可以使用以下命令创建myrowtype:
test=> SELECT CAST(ROW(1, 'x', '42.1') AS myrowtype);
row
------------
(1,x,42.1)
(1 row)
【讨论】: