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_target为ON 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 -这个链接很有帮助!