【问题标题】:How to run many inserts related data into PostgreSQL functions?如何在 PostgreSQL 函数中运行许多与插入相关的数据?
【发布时间】:2019-11-14 18:54:12
【问题描述】:

我在这种情况下寻求帮助: 我想创建将数据插入 3 个表的函数。

CREATE TABLE "public"."loads" (
  "id" int4 NOT NULL DEFAULT nextval('loads_id_seq'::regclass),
  "user_id" int4 NOT NULL,
  "name" varchar(60) COLLATE "pg_catalog"."default",
  "weight" float4 NOT NULL,
  "capacity" float4,
  "packing_type" int4,
  "price_request" bool
)

CREATE TABLE "public"."load_loading" (
  "load_id" int4 NOT NULL,
  "date_from" date,
  "date_to" date,
  "addr" varchar(120) COLLATE "pg_catalog"."default",
  "time_min" varchar(6) COLLATE "pg_catalog"."default",
  "time_max" varchar(6) COLLATE "pg_catalog"."default"
)

CREATE TABLE "public"."load_unloading" (
  "load_id" int4 NOT NULL,
  "date_from" date NOT NULL,
  "date_to" date,
  "addr" varchar(120) COLLATE "pg_catalog"."default",
  "time_min" varchar(6) COLLATE "pg_catalog"."default",
  "time_max" varchar(6) COLLATE "pg_catalog"."default"
)

我写了一个函数,但不能得到任何结果。

CREATE OR REPLACE FUNCTION "public"."add_load"("load_date_from" date, "loading_addr" varchar, "unloading_date_from" date, "unloading_addr" varchar, "_user_id" int4, "_name" varchar, "_weight" float4, "_capacity" float4, "_packing_type" int4, "_price_request" bool)
  RETURNS TABLE("_load" "public"."loads", "_load_load" "public"."load_loading", "_load_unload" "public"."load_unloading") AS $BODY$
      BEGIN
                RETURN QUERY
                WITH _load AS (
        INSERT INTO loads(user_id, name, weight, capacity, packing_type, price_request)
        VALUES(_user_id, _name, _weight, _capacity, _packing_type, _price_request) RETURNING *)
                , _load_load AS (INSERT INTO load_loading (load_id, date_from, addr)
                VALUES ((select id from _load), load_date_from, loading_addr) RETURNING *)
                ,   _load_unload AS (INSERT INTO load_unloading(load_id, date_from, addr) 
                VALUES ((SELECT id FROM _load), unloading_date_from, unloading_addr) RETURNING *)
                TABLE _load;
      END;
  $BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000

当我打电话给她时,我遇到了这个错误:

select * from add_load('10-10-2019', 'addr1', '10-11-2019', 'addr2', 123, 'name', 55, 55, 1, true)
> ERROR:  structure of query does not match function result type
DETAIL:  Returned type integer does not match expected type loads in column 1.
CONTEXT:  PL/pgSQL function add_load(date,character varying,date,character varying,integer,character varying,real,real,integer,boolean) line 3 at RETURN QUERY

我希望我的函数能看到 3 个表中所有列的结果;

还有一个问题,有没有办法得到这样的结果:

id、user_id、名称、重量、容量、packing_type、price_request、{load_loading data}、{load_unloading_data}

【问题讨论】:

    标签: sql postgresql function pg


    【解决方案1】:

    上面的错误是因为函数返回:

    RETURNS TABLE(_load loads, _load_load load_loading, _load_unload load_unloading) AS $BODY$
    

    您的查询返回:

    | id | user_id | name | weight | capacity | packing_type | price_request |
    

    如果你删除这部分:

    , _load_load load_loading, _load_unload load_unloading
    

    该功能将像我的DEMO一样工作

    关于你的第二个问题: 你应该用它自己的名字命名每一列来做到这一点。 这是该结果的DEMO。 这是功能:

    CREATE OR REPLACE FUNCTION add_load(load_date_from date
                                        , loading_addr varchar(140)
                                        , unloading_date_from date
                                        , unloading_addr varchar(140)
                                        , _user_id int4
                                        , _name varchar(140)
                                        , _weight float4
                                        , _capacity float4
                                        , _packing_type int4
                                        , _price_request bool)
      RETURNS TABLE( id int4, user_id1 int4, name varchar(60), weight float4, capacity float4,
                     packing_type int4, price_request bool, load_id1 int4, date_from1 date,
                     date_to1 date, addr1 varchar(120), time_min1 varchar(6),
                     time_max1 varchar(6), load_id2 int4, date_from2 date,  date_to2 date,
                     addr2 varchar(120), time_min2 varchar(6),  time_max2 varchar(6)
                     ) AS $BODY$
          BEGIN
    
                    RETURN QUERY 
                    WITH _load AS (
            INSERT INTO loads(user_id, name, weight, capacity, packing_type, price_request)
            VALUES(_user_id::int, _name::varchar, _weight::float, _capacity::float, _packing_type::int, _price_request::bool) RETURNING *)
                    , _load_load AS (INSERT INTO load_loading (load_id, date_from, addr)
                    VALUES ((select user_id::int from loads), load_date_from::date, loading_addr::varchar) RETURNING *)
                    ,   _load_unload AS (INSERT INTO load_unloading(load_id, date_from, addr) 
                    VALUES ((SELECT user_id::int FROM loads), unloading_date_from::date, unloading_addr::varchar) RETURNING *)
                    select * from _load, _load_load, _load_unload;
          END;
    
    $BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100
    ROWS 1000
    

    【讨论】:

    • 谢谢!你觉得如何,我可以从这样的 3 个表中返回数据吗?
    • 嗨@Rader,不客气,如果这有助于解决您的问题,那么请务必接受此答案正确。这样做的方法如下:stackoverflow.com/help/someone-answers 对于您在评论中提出的新问题,请检查:stackoverflow.com/questions/36717138/… 朝那个方向进行研究和编码。如果您遇到问题,请针对您的具体情况和问题提出一个新问题...
    猜你喜欢
    • 2014-08-12
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2019-02-02
    相关资源
    最近更新 更多