PostgreSQL ON冲突列引用是不明确的,但如何指定表列?



PL/pgSQL函数的一段如下所示:

INSERT INTO assistant.accesstoken
(
submission_id,
token,
expires
)
VALUES
(
v_submission_id,
assistant.pseudo_encrypt(v_submission_id),
CURRENT_TIMESTAMP + v_token_duration
)
ON CONFLICT (submission_id)
DO UPDATE SET
expires = CURRENT_TIMESTAMP + v_token_duration
RETURNING token
INTO v_accesstoken;

…给了我一个抱怨:

psycopg.errors.AmbiguousColumn: column reference "submission_id" is ambiguous
LINE 13:     ON CONFLICT (submission_id)
^
DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
QUERY:  INSERT INTO assistant.accesstoken
(
submission_id,
token,
expires
)
VALUES
(
v_submission_id,
assistant.pseudo_encrypt(v_submission_id),
CURRENT_TIMESTAMP + v_token_duration
)
ON CONFLICT (submission_id)
DO UPDATE SET
expires = CURRENT_TIMESTAMP + v_token_duration
RETURNING token
CONTEXT:  PL/pgSQL function assistant.evaluation_begin(character varying,character varying) line 115 at SQL statement

没有名为submission_id的变量Name仅作为列名存在。

不幸的是,为submission_id指定表似乎是一个错误:

ERROR:  syntax error at or near ")"
LINE 140:     ON CONFLICT (accesstoken.submission_id)

我怎么解决这个问题呢?如何前缀conflict_targetON CONFLICT在一种方式,它被接受?

另外,有人能告诉我一个来源,我可以学习如何变量和ON CONFLICT可以一起去吗?INSERT怎么会对"冲突"感兴趣呢?在PL/pgSQL变量中插入一行时,它甚至意味着什么?我真的很好奇……

PostgreSQL是否有过度热心的检查或其他什么?没有变量,在这个应用程序中的任何地方,都不会以in_,out_,inout_,r_v_为前缀,…

看起来这是在晚上关闭的,所以我不会在这个话题上花太多的时间,只是试着把它写得更好一点:

在评论中,klin提供了一个链接37.5.9。SQL函数返回解释为什么的表这发生了,然而问题仍然没有答案:如何一个前缀conflict_target告诉PostgreSQL,它是一个列,而不是一个变量?

此外,链接的"重复问题"不处理上述问题。我以为这个网站是想积累知识和信息——现在这个草率和不正确的关闭使它看起来像一个支持票处理(找到了解决方法,关闭它)。好吧,如果这是你想要的这个网站,那你就去做吧。

问题描述。因为返回TABLE与返回SETOF是等价的,所以"名称似乎只是局部作用域中的变量名(而不是匿名表的名称空间)。因此,包含submission_id的返回TABLE的定义(如下所示)是造成歧义的原因,并将其重命名,UPSERT的ON CONFLICT列/conflict_target不再是歧义的。(可能感觉像一个bug,但它不是…)

CREATE OR REPLACE FUNCTION
assistant.evaluation_begin(
in_course_id        VARCHAR,
in_uid              VARCHAR
)
RETURNS TABLE (
submission_id   INTEGER,
accesstoken     INTEGER
)
LANGUAGE PLPGSQL
SECURITY DEFINER
VOLATILE
CALLED ON NULL INPUT
AS $$

这个信息希望能让其他人看到这种情况(如果他们遇到类似的问题),这肯定会帮助解决这个问题,即使没有提供语法/工具来保持调用接口的完整性。

第二个问题仍然没有回答:一个变量在什么情况下可以成为一个有效的ON CONFLICT目标,它甚至意味着什么?可能这样的事情根本不存在,可能只是因为在所有歧义情况下都使用了相同的错误字符串。我个人怀疑情况就是这样。

但是既然现在已经结束了,我们就把它放在"问题解决了,找到了解决方法"。状态。谢谢你的klin -这个链接很有帮助!

最新更新