所以我在postgresql(版本12)中获得了以下架构
-- items table
CREATE TABLE items
(
id CHAR(27) PRIMARY KEY NOT NULL DEFAULT new_ksuid(),
name TEXT NOT NULL,
item_code VARCHAR(120) NOT NULL UNIQUE,
qty_loc JSONB NOT NULL DEFAULT '{
"whQty": []
}',
categories TEXT[],
upper INTEGER NOT NULL DEFAULT 999,
under INTEGER NOT NULL DEFAULT 0,
price_max DECIMAL(20, 2),
price_min DECIMAL(20, 2),
price_avg DECIMAL(20, 2),
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
existed BOOLEAN NOT NULL DEFAULT false
);
CREATE INDEX idx_name_items ON items USING gin (name gin_trgm_ops);
CREATE INDEX idx_item_code_items ON items USING gin (item_code gin_trgm_ops);
和以下功能
CREATE
OR REPLACE FUNCTION upd_item_amount(wh_id CHAR(27),
item_id CHAR(27),
qty NUMERIC) RETURNS VOID
LANGUAGE plpgsql AS
'
DECLARE
entry items%ROWTYPE;
BEGIN
SELECT EXISTS(
(SELECT id
INTO entry
FROM items, jsonb_array_elements(items.qty_loc -> ''whQty'')
WHERE value ? ''whId''
AND value ->> ''whId'' = wh_id
AND items.id = item_id)
);
IF FOUND THEN
WITH whq_idx AS (
WITH whq AS (
WITH QTY_LOC_AGG AS (
SELECT jsonb_agg(value) AS loc
FROM items,
jsonb_array_elements(qty_loc -> ''whQty'')
)
SELECT items.id, loc
FROM items,
QTY_LOC_AGG
)
SELECT (''{'' || index - 1 || '',qty}'')::text[] as path
FROM whq,
jsonb_array_elements(whq.loc) WITH ORDINALITY arr(wh_quantity, index)
WHERE (wh_quantity ->> ''whId'') = wh_id
AND whq.id = item_id
)
UPDATE items
SET qty_loc = jsonb_build_object(''whQty'',
jsonb_set(qty_loc -> ''whQty'', whq_idx.path, qty, false)
)
FROM whq_idx
WHERE items.id = item_id;
ELSE
UPDATE items
SET qty_loc = jsonb_build_object(''whQty'',
jsonb_set(qty_loc -> ''whQty'',
qty_loc -> ''whQty'' || ''{"whId": wh_id, "qty": qty}''
)
)
WHERE items.id = item_id;
END IF;
END';
在交互式psql中,我可以使用以下sql语句从第一个IF语句中执行UPDATE项目:
WITH whq_idx AS (
WITH whq AS (
WITH QTY_LOC_AGG AS (
SELECT jsonb_agg(value) AS loc
FROM items,
jsonb_array_elements(qty_loc -> ''whQty'')
)
SELECT items.id, loc
FROM items,
QTY_LOC_AGG
)
SELECT (''{'' || index - 1 || '',qty}'')::text[] as path
FROM whq,
jsonb_array_elements(whq.loc) WITH ORDINALITY arr(wh_quantity, index)
WHERE (wh_quantity ->> ''whId'') = wh_id
AND whq.id = item_id
)
UPDATE items
-- The error points to the following statement
SET qty_loc = jsonb_build_object(''whQty'',
jsonb_set(qty_loc -> ''whQty'', whq_idx.path, qty, false)
)
-- ^^^
FROM whq_idx
WHERE items.id = item_id;
但是当我通过“ SELECT upd_item_amount('warehouseID','itemID',amount_of_item)'调用它(函数)时,出现以下错误:
ERROR: function jsonb_set(jsonb, text[], numeric, boolean) does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
错误指向我的代码中的粗体部分。
有人可以指出我正确的方向吗?感谢任何帮助。非常感谢。
答案 0 :(得分:0)
错误:函数jsonb_set(jsonb,text [],numeric,boolean)没有 存在
提示:没有函数与给定的名称和参数类型匹配。你可能 需要添加显式类型转换
您传递jsonb_set“ qty”作为第三个参数,它是数字类型。但是jsonb_set将JSONB作为其第三个参数。 PostgreSQL拒绝将数字隐式转换为jsonb。您可以将其指定为"qty"::text::jsonb
来强制进行转换。