2017-06-02 42 views
0

繼續將多個數組的值插入表中。通過此post,創建一個函數來解析json輸入,然後將值插入到三個表中,並將先前插入的id作爲最後一個 插入的參數。使用索引

如果我想插入兩個數組到同一個表,我可以做

insert into t2 (car, car_type) 
    select json_array_elements_text(d::json -> 'car'),json_array_elements_text(d::json -> 'car_type')::int4 returning id; 
) 

如何使它具有如下指標工作?

功能:

create or replace function test_func(d json) 
returns void as $$ 
    begin 
with j as (select d) 
, a as (
    select car,brand,type, t1.id oid 
    from j 
    join json_array_elements_text(j.d->'cars') with ordinality t1(car,id) on true 
    join json_array_elements_text(j.d->'brands') with ordinality t2(brand,id) 
on t1.id = t2.id 
    join json_array_elements_text(j.d->'car_type') with ordinality t2(type,id) 
on t1.id = t2.id // this line apparently doesnt work, t2 has been joined twice 
) 
, n as (
insert into t1 (name) values (d::json -> 'name') returning id 
), c as (
    insert into t2 (cars,car_type) select car,type from a order by oid returning id // needs to insert two columns here from two arrays 
) 
, ag as (
    select array_agg(c.id) cid from c 
) 
insert into t3 (id, name_id, cars_id, brand) 
    select 1, n.id,cid[oid], brand 
    from a 
    join n on true 
    join ag on true 
; 
end; 
$$ language plpgsql; 

表:

CREATE TABLE t1 ("id" SERIAL PRIMARY KEY, "name" text NOT NULL); 
CREATE TABLE t2 ("id" SERIAL PRIMARY KEY, "cars" text NOT NULL, "car_type" int); 
CREATE TABLE t3 ("id" int, "name_id" int REFERENCES t1(id), "cars_id" int REFERENCES t2(id), "brand" text); 

測試:

select test_func('{"name":"john", "cars":["bmw X5 xdrive","volvo v90 rdesign"], "brands":["bmw","volvo"],"car_type":[1,1]}'); 

回答

0

您使用T2混疊兩種不同套 - 嘗試:

create or replace function test_func(d json) 
returns void as $$ 
    begin 
with j as (select d) 
, a as (
    select car,brand,car_type, t1.id oid 
    from j 
    join json_array_elements_text(j.d->'cars') with ordinality t1(car,id) on true 
    join json_array_elements_text(j.d->'brands') with ordinality t2(brand,id) 
on t1.id = t2.id 
    join json_array_elements_text(j.d->'car_type') with ordinality car_t(car_type,id) 
on t1.id = car_t.id 
) 
, n as (
insert into t1 (name) values (d::json -> 'name') returning id 
), c as (
    insert into t2 (cars,car_type) select car,car_type::int from a order by oid returning id -- needs to insert two columns here from two arrays 
) 
, ag as (
    select array_agg(c.id) cid from c 
) 
insert into t3 (id, name_id, cars_id, brand) 
    select 1, n.id,cid[oid], brand 
    from a 
    join n on true 
    join ag on true 
; 
end; 
$$ language plpgsql; 

結果:

t=# select * from t2; 
id |  cars  | car_type 
----+-------------------+---------- 
    1 | bmw X5 xdrive  |  1 
    2 | volvo v90 rdesign |  1 
(2 rows) 
+0

作爲最後的答案驚人的:)你只是讓我很快樂,謝謝維羅! – Wizer

+0

我的榮幸!週末愉快 :) –