关于sql:什么是行构造函数用于?

What is a row constructor used for?

在PostgreSQL中,ROW()函数用于什么?

具体来说有什么区别

1
SELECT ROW(t.f1, t.f2, 42) FROM t;

其中f1的类型为intf2的类型为text

1
CREATE TYPE myrowtype AS (f1 INT, f2 text, f3 NUMERIC);

你是令人困惑的抽象层次。正如其他答案已经指出的那样,CREATE TYPE仅在系统中注册(复合/行)类型。而ROW构造函数实际上返回一行。

使用ROW构造函数创建的行类型不会保留列名称,这在您尝试将行转换为JSON时会变得明显。

在此期间,ROW大多数时候只是一个噪音词。文件:

The key word ROW is optional when there is more than one expression in the list.

第一个表达式保留原始列名称,而第二个或第三个表单不保留原始列名称。考虑这个演示:

1
2
3
4
5
SELECT t AS t1, 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;

db <>在这里小提琴
SQL小提琴

r3j3演示ROW如何只是用来澄清事物的噪音词。

如果元素的数字和数据类型与行类型匹配,则可以将行(记录)强制转换为已注册的行类型 - 忽略输入字段的名称。

  • 在SQL中返回JSON对象数组(Postgres)

你问的是价值和类型之间的区别。

它与OO语言中的对象和类之间的区别大致相同。

在第一种情况下,您构建的值可用于比较,行写入或传递给接受复合参数的函数。

在第二种情况下,您将定义一个可以在函数或表定义中使用的类型。


行构造函数可用于构建要存储在复合类型表列中的复合值,或者传递给接受复合参数的函数。
此外,可以比较两个行值或使用IS NULL或IS NOT NULL测试行。

4.2.13。行构造函数

例:

1
2
3
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中是等价的:

1
2
3
4
5
6
7
8
9
10
11
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)

因为它们都创建了一个匿名记录:

1
2
3
4
5
6
7
8
9
10
11
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创建的记录可以对应于现有类型,例如:

1
CREATE TYPE myrowtype AS (f1 INT, f2 text, f3 NUMERIC);

你可以创建一个myrowtype

1
2
3
4
5
test=> SELECT CAST(ROW(1, 'x', '42.1') AS myrowtype);
    ROW    
------------
 (1,x,42.1)
(1 ROW)