如何在父表中插入单行,然后在PostgreSQL中的单个SQL中插入子表中
发布时间:2020-12-13 16:03:28 所属栏目:百科 来源:网络整理
导读:请在我的架构下面找到: CREATE TABLE reps ( id SERIAL PRIMARY KEY,rep TEXT NOT NULL UNIQUE);CREATE TABLE terms ( id SERIAL PRIMARY KEY,terms TEXT NOT NULL UNIQUE);CREATE TABLE shipVia ( id SERIAL PRIMARY KEY,ship_via TEXT NOT NULL UNIQUE);C
请在我的架构下面找到:
CREATE TABLE reps ( id SERIAL PRIMARY KEY,rep TEXT NOT NULL UNIQUE ); CREATE TABLE terms ( id SERIAL PRIMARY KEY,terms TEXT NOT NULL UNIQUE ); CREATE TABLE shipVia ( id SERIAL PRIMARY KEY,ship_via TEXT NOT NULL UNIQUE ); CREATE TABLE invoices ( id SERIAL PRIMARY KEY,customer TEXT NOT NULL CONSTRAINT customerNotEmpty CHECK(customer <> ''),term_id INT REFERENCES terms,rep_id INT NOT NULL REFERENCES reps,ship_via_id INT REFERENCES shipVia,... item_count INT NOT NULL,modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,version INT NOT NULL DEFAULT 0 ); CREATE TABLE invoiceItems ( id SERIAL PRIMARY KEY,invoice_id INT NOT NULL REFERENCES invoices ON DELETE CASCADE,name TEXT NOT NULL CONSTRAINT nameNotEmpty CHECK(name <> ''),description TEXT,qty INT NOT NULL CONSTRAINT validQty CHECK (qty > 0),price DOUBLE PRECISION NOT NULL ); 我试图使用可写CTE在一个SQL中插入发票及其发票项目.我目前坚持使用以下SQL语句: WITH new_invoice AS ( INSERT INTO invoices (id,customer,term_id,ship_via_id,rep_id,...,item_count) SELECT $1,$2,t.id,s.id,r.id,$26 FROM reps r JOIN terms t ON t.terms = $3 JOIN shipVia s ON s.ship_via = $4 WHERE r.rep = $5 RETURNING id ) INSERT INTO invoiceItems (invoice_id,name,qty,price,description) VALUES (new_invoice.id,$27,$28,$29,$30),(new_invoice.id,$31,$32,$33,$34),$35,$36,$37,$38); 当然,这个SQL是错误的,这就是PostgreSQL 9.2对它的看法: ERROR: missing FROM-clause entry for table "new_invoice" LINE 13: (new_invoice.id,$30) ^ ********** Error ********** ERROR: missing FROM-clause entry for table "new_invoice" SQL state: 42P01 Character: 704 有可能吗? 编辑1 我正在尝试以下版本: PREPARE insert_invoice_3 AS WITH new_invoice AS ( INSERT INTO invoices (id,item_count) SELECT $1,$26 FROM reps r JOIN terms t ON t.terms = $3 JOIN shipVia s ON s.ship_via = $4 WHERE r.rep = $5 RETURNING id ),v (name,description) AS ( VALUES ($27,($31,($35,$38) ) INSERT INTO invoiceItems (invoice_id,description) SELECT new_invoice.id,v.name,v.qty,v.price,v.description FROM v,new_invoice; 这是我得到的回报: ERROR: column "qty" is of type integer but expression is of type text LINE 19: SELECT new_invoice.id,v.descriptio... ^ HINT: You will need to rewrite or cast the expression. ********** Error ********** ERROR: column "qty" is of type integer but expression is of type text SQL state: 42804 Hint: You will need to rewrite or cast the expression. Character: 899 我猜v(名称,数量,价格,描述)是不够的,还必须指定数据类型.但是,v(名称,数量INT,描述)不起作用 – 语法错误. 编辑2 接下来,我刚刚尝试了第二个版本: PREPARE insert_invoice_3 AS WITH new_invoice AS ( INSERT INTO invoices (id,item_count) SELECT $1,$26 FROM reps r JOIN terms t ON t.terms = $3 JOIN shipVia s ON s.ship_via = $4 WHERE r.rep = $5 RETURNING id ) INSERT INTO invoiceItems (invoice_id,description) ( SELECT i.id,$30 FROM new_invoice i UNION ALL SELECT i.id,$34 FROM new_invoice i UNION ALL SELECT i.id,$38 FROM new_invoice i ); 这是我得到的: ERROR: column "qty" is of type integer but expression is of type text LINE 15: SELECT i.id,$30 FROM new_invoice i ^ HINT: You will need to rewrite or cast the expression. ********** Error ********** ERROR: column "qty" is of type integer but expression is of type text SQL state: 42804 Hint: You will need to rewrite or cast the expression. Character: 759 似乎是同样的错误.有趣的是,如果我删除所有UNION ALL并只留下一个SELECT语句 – 它可以工作! 编辑3 为什么我要投射参数?是否可以在CTE中指定列的类型? 解决方法
PostgreSQL对VALUES子句有如此扩展的解释,它可以单独用作子查询.
因此,您可以用以下形式表达您的查询: WITH new_invoice AS ( INSERT INTO ... RETURNING id ),v(a,b,c,d) AS (values ($27,... ) INSERT INTO invoiceItems (invoice_id,a,d FROM v,new_invoice; 这假设您想要插入new_invoice的笛卡尔积和值,如果new_invoice实际上是单行值,这通常是有意义的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |