2016-09-29 80 views
1

我有一个函数,我想要创建一个用户,插入用户到表和IF提供添加用户到角色。我可以创建用户并将它们添加到使用第一个函数创建的表格中,但我无法有条件地将它们添加到组中。我想要选择不将用户添加到角色或包含角色并将该角色授予用户。这里是我的功能,以创建工作Postgres函数与嵌套IF

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; 

任何帮助是非常赞赏的用户。

回答

2

您缺少嵌套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; 
0

我结束了修改从@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;