在这段代码中,当我运行:
CREATE TABLE IF NOT EXISTS setup_workspace_result (
path TEXT,
workspace_id BIGINT
);
DROP FUNCTION IF EXISTS public.setup_workspace;
CREATE OR REPLACE FUNCTION setup_workspace(refresh_token TEXT)
RETURNS setup_workspace_result
AS $$
DECLARE
user_email TEXT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'email');
workspace_name TEXT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'hd');
name TEXT := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'name');
is_admin BOOLEAN := ((current_setting('request.jwt.claims'::text, TRUE))::JSON ->> 'isAdmin');
workspace_id BIGINT;
user_id BIGINT;
result setup_workspace_result;
BEGIN
-- Check if user already exists
SELECT users.id, users.workspace_id INTO user_id, workspace_id FROM users WHERE email = user_email;
IF user_id IS NOT NULL THEN
-- User already exists, return workspace_id
UPDATE service_google
SET token = refresh_token
WHERE service_google.workspace_id = workspace_id;
result.workspace_id := workspace_id;
result.path := 'login';
ELSE
-- Insert data into tables
INSERT INTO users (email, name)
VALUES (user_email, name) RETURNING id INTO user_id;
INSERT INTO workspaces (domain_name, created_by)
VALUES (workspace_name, user_id) RETURNING id INTO workspace_id;
INSERT INTO super_admins (workspace_id, user_id)
VALUES (workspace_id, user_id);
result.workspace_id := workspace_id;
result.path := 'signup';
END IF;
RETURN result;
END;
$$ LANGUAGE plpgsql;
出现以下错误:
{
code: '42702',
details: 'It could refer to either a PL/pgSQL variable or a table column.',
hint: null,
message: 'column reference "workspace_id" is ambiguous'
}
你知道为什么我会得到这个,我如何解决它?
2条答案
按热度按时间hpxqektj1#
您有一个名为
workspace_id
的列,并且您声明了一个同名的变量。这是命名冲突的秘诀。请不要这样做。尽可能使用与所有相关列名不同的变量名。我喜欢在变量名前面加上下划线,例如:
_workspace_id
。这只是解决这个问题的许多方法之一。并且表限定所有可能冲突的列名。这绝对是个好主意。相关:
修复竞态
在修复了出现的错误之后,函数中还有更多不太明显的问题。
基本上,这是一个典型的 ”
SELECT
或INSERT
“ 的情况,当前的实现容易出现竞争条件。首先阅读:然后考虑这个重写:
还修复了命名冲突问题,并添加了一些其他改进。
xfb7svmp2#
很多数据库,包括postgres,在变量名和列名冲突时会感到困惑。为了避免这种情况,我在变量名前面加上下划线,这样它们就不会冲突,如下所示:
它还使代码更容易阅读,因为变量很突出。
您可以根据自己的喜好使用不同的样式,例如两个下划线
__workspace_id
或v_
(如v_workspace_id
),以更好地适应您公司可能具有的命名标准。