sql - 用于外键插入的 PostgreSQL 嵌套 INSERTs/WITHs

标签 sql database postgresql

我正在使用 PostgreSQL 9.3,我正在尝试编写一个 SQL 脚本来为单元测试插入一些数据,但我遇到了一些问题。

假设我们有三个表,结构如下:

------- Table A -------    -------- Table B --------    -------- Table C --------
id  | serial NOT NULL      id   | serial NOT NULL       id   | serial NOT NULL
foo | character varying    a_id | integer NOT NULL      b_id | integer NOT NULL
                           bar  | character varying     baz  | character varying

B.a_idC.b_id 是表 Aid 列的外键和 B,分别。

我想做的是用纯 SQL 在这三个表中的每一个中插入一行,而不是将 ID 硬编码到 SQL 中(在运行此脚本之前对数据库进行假设似乎是不可取的,因为如果这些假设发生变化,我将不得不返回并重新计算所有测试数据的正确 ID)。

请注意,我确实意识到我可以通过编程方式执行此操作,但通常编写纯 SQL 比编写执行 SQL 的程序代码要简洁得多,因此它对测试套件数据更有意义。

无论如何,这是我编写的我认为可行的查询:

WITH X AS (
    WITH Y AS (
        INSERT INTO A (foo)
        VALUES ('abc')
        RETURNING id
    )
    INSERT INTO B (a_id, bar)
    SELECT id, 'def'
    FROM Y
    RETURNING id
)
INSERT INTO C (b_id, baz)
SELECT id, 'ghi'
FROM X;

但是,这不起作用,结果 PostgreSQL 告诉我:

ERROR:  WITH clause containing a data-modifying statement must be at the top level

有没有正确的方法来编写这种类型的查询,而无需对 ID 值进行硬编码?

(您可以找到包含此示例的 fiddle here。)

最佳答案

普通表表达式不要嵌套,一个接一个写就可以了:

WITH Y AS (
  INSERT INTO A (foo)
  VALUES ('abc')
  RETURNING id
), x as (
  INSERT INTO B (a_id, bar)
  SELECT id, 'def'
  FROM Y
  RETURNING id
)
INSERT INTO C (b_id, baz)
SELECT id, 'ghi'
FROM X;

关于sql - 用于外键插入的 PostgreSQL 嵌套 INSERTs/WITHs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21386772/

相关文章:

mysql - MySQL 中 Group By 查询中的子组

sql - 获取 SQL Server 中某个字符之后和之前的所有内容

mysql - 返回 "name"列来代替 mysql 中的 ID

postgresql - Plpgsql:如何在声明部分为变量赋值?

java - 如何使用 Postgresql 数据库在 Heroku 上部署?

mysql - 如何为每条父记录仅选择 1 个子表项?

SQL 连接查询帮助

c++ - 如何通过函数 C++ 链接数组值

database - 取消记录更改

c# - 用于 Postgre SQL 10 的 linq2db 提供程序