具有嵌套 IF 的 Postgres 函数
Postgres function with nested IF
我有一个功能,我正在尝试创建一个用户,将用户插入到 table 中,如果提供,则将用户添加到一个角色中。我可以创建用户并将它们添加到我用第一个函数创建的 table 中,但我不能有条件地将它们添加到组中。我想要选择不将用户添加到角色或包含角色并将该角色授予用户。这是我创建有效用户的函数
CREATE OR REPLACE FUNCTION create_user(
new_user character varying,
temp_password character varying,
grant_role text default NULL)
RETURNS text AS
$BODY$
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user) THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''',
date(now()),
date(now() + interval ''1 days''));');
RETURN 'CREATED ROLE';
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;
ALTER FUNCTION create_user(character varying, character varying)
OWNER TO postgres;
我想做这样的伪代码
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
&& IF NOT EXISTS (SELECT rolname FROM pg_roles WHERE rolname = grant_role and rolname <> 'postgres')
&& grant_role IS NOT NULL THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSE
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
END IF;
END;
非常感谢任何帮助。
您缺少嵌套 ELSEIF
的条件。在我添加注释行的地方填充它,它应该可以按预期使用嵌套
IF ... THEN ... [ELSEIF ...] [ELSE ...] END IF;
代码:
BEGIN
IF NOT EXISTS (
SELECT usename
FROM pg_catalog.pg_user
WHERE usename not in ('postgres','repl','pgpool')
AND usename = new_user
)
THEN
IF NOT EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
) AND grant_role IS NOT NULL
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSEIF -- you forgot to specify the condition
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
我最终将@Kamil G. 的答案修改为以下函数。他的回答让我到达了我需要去的地方。
CREATE OR REPLACE FUNCTION create_user(
new_user character varying,
temp_password character varying,
grant_role text default NULL)
RETURNS text AS
$BODY$
BEGIN
IF NOT EXISTS (
SELECT usename
FROM pg_catalog.pg_user
WHERE usename not in ('postgres','repl','pgpool')
AND usename = new_user
) AND grant_role IS NOT NULL
THEN
IF EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
)
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSE
RETURN 'NO USER CREATED';
END IF;
ELSEIF NOT EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
) AND grant_role IS NULL
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
END;
我有一个功能,我正在尝试创建一个用户,将用户插入到 table 中,如果提供,则将用户添加到一个角色中。我可以创建用户并将它们添加到我用第一个函数创建的 table 中,但我不能有条件地将它们添加到组中。我想要选择不将用户添加到角色或包含角色并将该角色授予用户。这是我创建有效用户的函数
CREATE OR REPLACE FUNCTION create_user(
new_user character varying,
temp_password character varying,
grant_role text default NULL)
RETURNS text AS
$BODY$
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user) THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''',
date(now()),
date(now() + interval ''1 days''));');
RETURN 'CREATED ROLE';
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;
ALTER FUNCTION create_user(character varying, character varying)
OWNER TO postgres;
我想做这样的伪代码
BEGIN
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
&& IF NOT EXISTS (SELECT rolname FROM pg_roles WHERE rolname = grant_role and rolname <> 'postgres')
&& grant_role IS NOT NULL THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSE
IF NOT EXISTS (SELECT usename FROM pg_catalog.pg_user
Where usename not in ('postgres','repl','pgpool')
and usename = new_user)
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
END IF;
END;
非常感谢任何帮助。
您缺少嵌套 ELSEIF
的条件。在我添加注释行的地方填充它,它应该可以按预期使用嵌套
IF ... THEN ... [ELSEIF ...] [ELSE ...] END IF;
代码:
BEGIN
IF NOT EXISTS (
SELECT usename
FROM pg_catalog.pg_user
WHERE usename not in ('postgres','repl','pgpool')
AND usename = new_user
)
THEN
IF NOT EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
) AND grant_role IS NOT NULL
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSEIF -- you forgot to specify the condition
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', new_user);
END IF;
END;
我最终将@Kamil G. 的答案修改为以下函数。他的回答让我到达了我需要去的地方。
CREATE OR REPLACE FUNCTION create_user(
new_user character varying,
temp_password character varying,
grant_role text default NULL)
RETURNS text AS
$BODY$
BEGIN
IF NOT EXISTS (
SELECT usename
FROM pg_catalog.pg_user
WHERE usename not in ('postgres','repl','pgpool')
AND usename = new_user
) AND grant_role IS NOT NULL
THEN
IF EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
)
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('GRANT ' || grant_role || ' to ' || new_user ||';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()), date(now() + interval ''1 days''));');
RETURN 'CREATED USER WITH ROLE';
ELSE
RETURN 'NO USER CREATED';
END IF;
ELSEIF NOT EXISTS (
SELECT rolname
FROM pg_roles
WHERE rolname = grant_role
AND rolname <> 'postgres'
) AND grant_role IS NULL
THEN
EXECUTE format('CREATE USER ' || new_user || ' with password ''' || temp_password || ''';');
EXECUTE format('insert into open_sesame (user_name, last_change_date, next_change_date) VALUES( ''' || new_user || ''', date(now()),date(now() + interval ''1 days''));');
RETURN 'CREATED USER ONLY';
ELSE
RETURN 'NO USER CREATED';
END IF;
END;