在 INSERT 语句的 RETURNING 中包含 table 名称

Include table name in RETURNING from INSERT statement

我有一个 INSERT 语句这样 returns 插入的 ID:

INSERT INTO encyclopedias (page_id)
SELECT page.id FROM pages
RETURNING id;

INSERT INTO cookbooks (page_id)
SELECT page.id FROM pages
RETURNING id;

其中 returns 类似于:

 id 
----
1
2

 id 
----
3
4

解析输出时,我想告诉 table ID 来自哪个,例如:

encyclopedia id
----
1
2

cookbook id
----
3
4

或:

table, id
----
encyclopedias, 1
encyclopedias, 2

table, id
----
cookbooks, 3
cookbooks, 4

我该怎么做?

其中一种方法是使用 WITH 查询:

WITH inserts AS (
INSERT INTO encyclopedias (page_id)
SELECT page.id FROM pages
RETURNING id
)
SELECT inserts.id AS encyclopedia_id;

WITH inserts AS (
INSERT INTO encyclopedias (page_id)
SELECT page.id FROM pages
RETURNING id
)
SELECT 'encyclopedia' AS "table", inserts.id AS "id";

有关 PostgreSQL Documentation page about INSERT

的更多信息

returning 子句中使用列别名和常量:

insert into t(x) values(1) returning x as xx, 'the table' as table_name;
╔════╤════════════╗
║ xx │ table_name ║
╠════╪════════════╣
║  1 │ the table  ║
╚════╧════════════╝

更新:

此外,您还可以为 psql 指定多种输出格式设置,例如:

$ echo "
> \pset format unaligned
> \pset tuples_only on
> \echo --==## foo ##==--
> select 1,2,3;" | psql
Output format is unaligned.
Tuples only is on.
--==## foo ##==--
1|2|3

the documentation 中查找更多信息。

有一个简单的解决方案可以使用系统列 tableoid 自动执行此操作。

这是源 table 的内部 OID(对象 ID),可以转换为 regclass 以将其转换为实际的 table 名称。

INSERT INTO encyclopedias (page_id)
SELECT id FROM pages
RETURNING tableoid::regclass::text AS table, page_id AS id;

Returns 您想要的输出正好是:

table         | id
--------------+----
encyclopedias | 1
encyclopedias | 2

如果您更改 FROM 子句中的 table(如您的示例),则无需调整 RETURNING 子句。

相关:

  • Get the name of a row's source table when querying the parent it inherits from