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
它应该实现的是
if cte_input_data.data_type_id = 1 update master_config_details set date_value = cte.value
if cte_input_data.data_type_id = 2 update master_config_details set number_value = cte.value
if cte_input_data.data_type_id = 3 update master_config_details set string_value = cte.value
下面的代码应该对 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 中获取它。
我有一个 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
它应该实现的是
if cte_input_data.data_type_id = 1 update master_config_details set date_value = cte.value
if cte_input_data.data_type_id = 2 update master_config_details set number_value = cte.value
if cte_input_data.data_type_id = 3 update master_config_details set string_value = cte.value
下面的代码应该对 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 中获取它。