2016-09-29 290 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;