我正在使用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_id和C.b_id分别是表A和B的id列的外键.
我想要做的是使用纯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值进行硬编码?
(你可以找到一个包含这个例子的小提琴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,'ghi' FROM X;