在 PostgreSQL 数据库中,我有一个名为RELATIONSHIP
的表:
| SURVEY_ID | EMPLOYEE | ORGANIZATION_NAME | STATUS (default: false) |
|--------------------------------------|----------|-------------------|-------------------------|
| d5f9c639-13e6-42c1-9043-30783981724b | Mark | Apple | false |
| d5f9c639-13e6-42c1-9043-30783981724b | Bob | Apple | true |
此表具有唯一的密钥,您可以通过下一个sql语句创建该密钥:
ALTER TABLE RELATIONSHIP ADD CONSTRAINT RELATIONSHIP_UNIQUE_KEY UNIQUE (SURVEY_ID, EMPLOYEE);
让我们说我想按RELATIONSHIP
表中的过程添加新的3条记录。
CALL creator(
'd5f9c639-13e6-42c1-9043-30783981724b',
ARRAY['Mark', 'Bob', 'Kate'],
ARRAY['Google', 'Google', 'HP']
);
如果SURVEY_ID
和EMPLOYEE
的值是唯一的,并且表中没有这样的记录,我想将该记录添加到表中。例如,第三条记录在开始时不在表中。因此,我添加了它。同时,如果SURVEY_ID
和EMPLOYEE
的值不是唯一的,并且表中有这样的记录,我不想添加它们。例如第一条记录和第二条记录。问题是,如果状态为true,我需要更新ORGANIZATION_NAME
列的值。例如,第一条记录的状态为false。因此,我需要将ORGANIZATION_NAME
列的值从Apple更新为Google。第二条记录不变。如何正确进行此更新?
换句话说,我最终想要这样的结果:
| SURVEY_ID | EMPLOYEE | ORGANIZATION_NAME | STATUS (default: false) |
|--------------------------------------|----------|-------------------|-------------------------|
| d5f9c639-13e6-42c1-9043-30783981724b | Mark | Google | false |
| d5f9c639-13e6-42c1-9043-30783981724b | Bob | Apple | true |
| d5f9c639-13e6-42c1-9043-30783981724b | Kate | HP | false |
现在我的程序如下:
CREATE OR REPLACE PROCEDURE creator(SURVEY_IDENTIFIER uuid, EMPLOYEES VARCHAR[], ORGANIZATION_NAMES VARCHAR[]) AS $FUNCTION$
BEGIN
INSERT INTO RELATIONSHIP (SURVEY_ID, EMPLOYEE, ORGANIZATION_NAME)
SELECT
SURVEY_IDENTIFIER SURVEY_ID,
EMPLOYEE FROM UNNEST(ARRAY[EMPLOYEES]) EMPLOYEE,
ORGANIZATION_NAME FROM UNNEST(ARRAY[ORGANIZATION_NAMES]) ORGANIZATION_NAME
ON CONFLICT ON CONSTRAINT RELATIONSHIP_UNIQUE_KEY
DO NOTHING;
END;
$FUNCTION$ LANGUAGE plpgsql;
问题:
SQL Error [21000]: ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time Tip: Ensure that no rows proposed for insertion within the same command have duplicate constrained values.
按照您的建议添加SELECT DISTINCT
后,该问题已部分解决。
如果我使用这样的值调用过程,则没有错误:
CALL creator(
'99c89a24-fff2-4cbc-a542-b1e956a352f9',
ARRAY['Mark', 'Kate', 'Mark'],
ARRAY['NEXT', 'U12', 'NEXT']
);
如果我用这样的值调用过程,问题就是蓝绿色:
CALL creator(
'99c89a24-fff2-4cbc-a542-b1e956a352f9',
ARRAY['Mark', 'Kate', 'Mark'],
ARRAY['NEXT', 'U12', 'HP']
);
您认为在这种情况下可以做什么?我认为在这种情况下,最好的方法是设置ORGANIZATION_NAME
的最后一个值。最好设置HP
。
答案 0 :(得分:1)
您要更改ON CONFLICT
子句:
INSERT INTO RELATIONSHIP (SURVEY_ID, EMPLOYEE, ORGANIZATION_NAME)
SELECT SURVEY_IDENTIFIER as SURVEY_ID,
u.EMPLOYEE, u.ORGANIZATION
FROM UNNEST(ARRAY[EMPLOYEES],
ARRAY[ORGANIZATION_NAMES]
) u(EMPLOYEE, ORGANIZATION_NAME)
ON CONFLICT ON CONSTRAINT RELATIONSHIP_UNIQUE_KEY
DO UPDATE SET ORGANIZATION_NAME = EXCLUDED.ORGANIZATION_NAME
WHERE NOT RELATIONSHIP.STATUS;
请注意,我还更改了FROM
子句以并行取消嵌套数组。我无法识别问题中查询中使用的双重FROM
语法。
对于最后一个问题,我认为此版本的查询将起作用:
SELECT DISTINCT ON (u.EMPLOYEE) SURVEY_IDENTIFIER as SURVEY_ID,
u.EMPLOYEE, u.ORGANIZATION
FROM UNNEST(ARRAY[EMPLOYEES],
ARRAY[ORGANIZATION_NAMES]
) WITH ORDINALITY u(EMPLOYEE, ORGANIZATION_NAME, n)
ORDER BY u.EMPLOYEE, n DESC