查询在Postgres中的JSONB_SET的JSONB参数中

发布于 2025-01-29 13:50:29 字数 1602 浏览 3 评论 0原文

我正在使用go和“ github.com/jackc/pgx/v4/pgxpool”

我表中的一个字段具有json,我需要在一个查询中更新两个键。

第一个问题是一次更新几个键,但我认为现在使用嵌套JSONB_SET来工作正常。

一个更大的问题是在这种情况下,参数替换的工作原理。

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     $3,
                     true), 
                '{second_key_name}', 
                $4,
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

但是,这产生了类型JSON 错误的无效输入语法。添加to_jsonb():: JSONB aboun/code> abount/of the参数之后($ 3,4美元)无济于事。

以下是pgx库的使用方式将参数传递给查询。这两个键值均为String类型。

err := pool.QueryRow(ctx, myQuery,
        id,
        first_column,
        first_key_value,
        second_key_value
    ).
        Scan(...)

经过一些实验后,使它起作用的一种方法是使用JSONB_BUILD_ARRAY,然后获取0-第一个项目。看起来完全不可读,我几乎确定必须有一种更简单的方法来实现这一目标。

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     jsonb_array_element(jsonb_build_array($3::text), 0), 
                     true), 
                '{second_key_name}', 
                jsonb_array_element(jsonb_build_array($4::text), 0),
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

I am using Go and "github.com/jackc/pgx/v4/pgxpool".

One of the fields in my table has json and I need to update two keys in one query.

The first problem was to update several keys at once but I think it works fine now with a nested jsonb_set.

A bigger problem is how parameter substitution works in this case.

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     $3,
                     true), 
                '{second_key_name}', 
                $4,
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

This yields, however, the invalid input syntax for type json error. Adding either to_jsonb() or ::jsonb around/after the parameters ($3, $4) didn't help.

Below is how the pgx library is used to pass the arguments to the query. Both key value are of string type.

err := pool.QueryRow(ctx, myQuery,
        id,
        first_column,
        first_key_value,
        second_key_value
    ).
        Scan(...)

After some experimenting, it seems that one way to make it work is to use jsonb_build_array and then get the 0-th item. That looks totally unreadable and I am almost sure there must be a simpler way to achieve this.

UPDATE my_table
    SET 
        first_column=$2,
        json_column = JSONB_SET(JSONB_SET(
                     json_column::jsonb, 
                    '{first_key_name}', 
                     jsonb_array_element(jsonb_build_array($3::text), 0), 
                     true), 
                '{second_key_name}', 
                jsonb_array_element(jsonb_build_array($4::text), 0),
                true),
        updated_at  = now() at time zone 'utc'
    WHERE id=$1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡绿茶香 2025-02-05 13:50:29

您可以在此处使用||操作员。
最初是说记录看起来像这样:

{"a":"b","key2":"value2"}

在更新后,

update dummy set j=j::jsonb||'{"a": "new_value"}
{"a":"new_value","key2":"value2"}

请记住它替换了顶级键,如果发现否则会创建一个新键。使用jsonb_build_object在||右侧创建JSON对象操作员

You could use || operator here.
Initially lets say the record look like this:

{"a":"b","key2":"value2"}

After update

update dummy set j=j::jsonb||'{"a": "new_value"}
{"a":"new_value","key2":"value2"}

Remember it replaces top level keys if found otherwise create a new key. use jsonb_build_object to create json object on right side of || operator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文