我user_product_mapping為每個用戶存盤產品:
DROP TABLE IF EXISTS user_product_mapping;
CREATE TABLE user_product_mapping
(
id SERIAL NOT NULL PRIMARY KEY,
user_id INT,
product_info json NOT NULL,
CONSTRAINT fk_user FOREIGN KEY(user_id) REFERENCES users(user_id)
);
樣本值:
INSERT INTO user_product_mapping (user_id, product_info)
VALUES
(1, '{"product": "laptop,mobile"}'),
(2, '{"product": "charger"}'),
(3, '{"product": "mobile,mouse,charger"}')
;
現在我想將新產品作為“筆記本電腦”添加到現有的 user_id 2。
預期結果:
user_id | product_info
---------------------------------------
2 | {"product": "charger,laptop"}
我試圖追加但面臨一個問題:
UPDATE user_product_mapping
SET product_info = product_info || '{"laptop"}'
WHERE user_id = 2;
Error:
ERROR: column "product_info" is of type json but expression is of type text
LINE 2: SET product_info = product_info || '{"123e4567-e89b-12d3-a45...
^
HINT: You will need to rewrite or cast the expression.
你能建議前進的方向嗎?
uj5u.com熱心網友回復:
UPDATE user_product_mapping
SET product_info = json_build_object('product', concat_ws(',', NULLIF(product_info->>'product', ''), 'laptop'))
WHERE user_id = 2;
甚至可以在缺少“產品”鍵、具有空值或空串列的情況下正常作業。但它是在給豬涂口紅。
它燒毀到提取文本值,將另一個專案連接到串列(安全地),并分配一個新包裝的 JSON 值。看:
- 如何連接 Postgres SELECT 中的列?
使用 JSON 時,資料型別jsonb會更實用,因此您可以使用jsonb_set():
SET product_info = jsonb_set (product_info, '{product}', to_jsonb(concat_ws(',', NULLIF(product_info->>'product', ''), 'laptop')))
更實用的是,使用 JSON 陣列而不是文本值串列。
SET product_info = product_info || jsonb '"laptop"'
作為 Postgres 的 text: 陣列,這會更實用text[]。
SET product_info = product_info || 'laptop'
但是您可能真正應該做的是正確規范化的多對多實作:
- 如何在 PostgreSQL 中實作多對多關系?
- 如何在 Postgres 9.4 中對 JSONB 型別的列執行更新操作
INSERT然后,您使用普通的or添加和洗掉產品DELETE,不會像上述所有操作那樣對同一用戶造成并發寫入問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/479993.html
標籤:sql json PostgreSQL
