【问题标题】:Can postgreSQL OnConflict combine with JSON obejcts?postgreSQL On Conflict 可以与 JSON 对象结合使用吗?
【发布时间】:2021-11-18 15:42:56
【问题描述】:

我想在 PostgreSQL 中执行条件插入。比如:

INSERT INTO {TABLE_NAME} (user_id, data) values ('{user_id}', '{data}') 
WHERE not exists(select 1 from files where user_id='{user_id}' and data->'userType'='Type1')

很遗憾,在 PostGreSQL 中 insert 和 where 不配合。什么可能是适合我的查询的语法?我正在考虑ON CONFLICT,但找不到将它与 JSON 对象一起使用的语法。 (示例中的数据)

有可能吗?

【问题讨论】:

    标签: postgresql sql-insert


    【解决方案1】:

    将 VALUES 部分重写为 SELECT,然后可以使用 WHERE 条件:

    INSERT INTO { TABLE_NAME } ( user_id, data ) 
    SELECT
        user_id,
        data 
    FROM
        ( VALUES ( '{user_id}', '{data}' ) ) sub ( user_id, data ) 
    WHERE
        NOT EXISTS ( 
            SELECT 1 
            FROM files 
            WHERE user_id = '{user_id}' 
            AND data -> 'userType' = 'Type1' 
            );
    

    但是,不能保证 WHERE 条件有效!另一个尚未提交的事务对此查询不可见。这可能会导致数据质量问题。

    【讨论】:

      【解决方案2】:

      您可以使用INSERT ... SELECT ... WHERE ...

      INSERT INTO elbat
                  (user_id,
                   data)
                  SELECT 'abc',
                         'xyz' 
                  WHERE NOT EXISTS (SELECT *
                                           FROM files
                                           WHERE user_id = 'abc'
                                           AND data->>'userType' = 'Type1')
      

      看起来您正在使用宿主语言创建查询。不要使用字符串连接或插值来获取其中的值。这很容易出错,并使您的应用程序容易受到 SQL 注入攻击。查找如何在您的宿主语言中使用参数化查询。很可能对于表名参数不能使用。您需要一些其他方法来将名称列入白名单或正确引用它们。

      【讨论】:

        猜你喜欢
        • 2021-03-05
        • 2016-01-23
        • 1970-01-01
        • 1970-01-01
        • 2016-05-06
        • 2016-04-14
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        相关资源
        最近更新 更多