POSTGRES INSERT/UPDATE 关于使用 WITH CTE 的冲突

POSTGRES INSERT/UPDATE ON CONFLICT using WITH CTE

我有一个 table 如下所示。我正在尝试根据 CTE 中的值合并到此 table 中。但是当我尝试更新 table 时出现冲突,它无法获取 CTE

中的值
CREATE TABLE IF NOT EXISTS master_config_details
(
    master_config_id    INT          NOT NULL,
    account_id          INT          NOT NULL,
    date_value          TIMESTAMP(3) NULL,
    number_value        BIGINT       NULL,
    string_value        VARCHAR(50)  NULL,
    row_status          SMALLINT     NOT NULL,
    created_date        TIMESTAMP(3) NOT NULL,
    modified_date       TIMESTAMP(3) NULL,
    CONSTRAINT pk_master_config_details PRIMARY KEY (master_config_id, account_id, row_status)
);

INSERT INTO master_config_details VALUES (
    1,  11, NULL,100,NULL,          0,  '2020-11-18 12:01:18',  '2020-11-18 12:02:31');

select * from master_config_details;`

现在使用 cte 我想 insert/update 在这个 table 中记录。下面是我用来做同样事情的代码。当 table 中已经存在记录时,我想根据 cte (cte_input_data.data_type_id ) 中的 data_type_id 值更新 table,但它失败并出现错误。

SQL Error [42703]: ERROR: column excluded.data_type_id does not exist

它应该实现的是

下面的代码应该对 table master_config_details.number_value = 22 进行更新,因为该组合中已经有一条记录(master_config_id、account_id、row_status) 是 (1,11,1)(运行 这可以从 master_config_details 中查看记录 select *;)但它会抛出一个错误

SQL Error [42703]: ERROR: column excluded.data_type_id does not exist

   WITH cte_input_data AS (
                select
                        1 AS master_config_id 
                        ,11 AS account_id
                        ,2 AS data_type_id 
                        ,'22' AS value
                        ,1 AS row_status)

    INSERT INTO master_config_details  
        SELECT 
                cte.master_config_id
                ,cte.account_id
                ,CASE WHEN cte.data_type_id  = 1 THEN cte.value::timestamp(3) ELSE NULL END AS date_time_value  
                ,CASE WHEN cte.data_type_id  = 2 THEN cte.value::integer ELSE NULL END AS number_value  
                ,CASE WHEN cte.data_type_id  = 3 THEN cte.value ELSE NULL END AS string_value 
                ,1
                ,NOW() AT TIME ZONE 'utc'
                ,NOW() AT TIME ZONE 'utc'
        FROM cte_input_data cte  
        ON CONFLICT (master_config_id,account_id,row_status)
        DO UPDATE SET
            date_value              = CASE WHEN  excluded.data_type_id = 1 THEN excluded.date_time_value::timestamp(3) ELSE NULL END 
            ,number_value               = CASE WHEN  excluded.data_type_id = 2 THEN excluded.number_value::integer ELSE NULL END 
     
            ,string_value           = CASE WHEN  excluded.data_type_id = 3 THEN excluded.string_value ELSE NULL END 
            ,modified_date = NOW() AT TIME ZONE 'utc';



   

特殊排除 table 用于参考最初建议插入的值。 所以你得到这个错误是因为这个列在你的目标 table 中不存在,所以在特殊排除 table 中。它仅存在于您的 cte 中。 作为解决方法,您可以 select 在冲突语句中使用嵌套 select 从 cte 中获取它。