如果 Oracle 用户不存在则创建它

Creating an Oracle User if it doesn't already exist

我正在尝试创建一个脚本来创建用户如果他们尚不存在

CREATE USER "Kyle" PROFILE "DEFAULT" IDENTIFIED BY "password" ACCOUNT UNLOCK
WHERE NOT IN  //Also tried 'WHERE NOT EXISTS'
(
    SELECT username FROM all_users WHERE username = 'Kyle'
)

报错如下:

SQL Error: ORA-00922: missing or invalid option

我能够在 SQL Server 2008 中使用:

IF NOT EXISTS
(SELECT name FROM master.sys.server_principals
WHERE name = 'Kyle')
BEGIN
    CREATE LOGIN Kyle WITH PASSWORD = 'temppassword' MUST_CHANGE, CHECK_EXPIRATION=ON, CHECK_POLICY=ON
END

Oracle 中是否有类似的方法来在尝试创建新用户之前检查用户是否已经存在?

你需要写一个pl/sql块。查看示例 here

您可以使用一些 pl/sql 代码检查用户是否存在于 all_users table 中:

SELECT count(*) INTO v_count_user
FROM all_users
WHERE username = 'Kyle'

然后在IF条件中使用v_count_user有条件地执行create user语句。

SQL Server 中可用的 IF NOT EXISTS 语法在 Oracle 中不可用。

通常,Oracle 脚本只是执行 CREATE 语句,如果对象已经存在,您将收到一个错误提示,您可以忽略该错误。这就是所有标准 Oracle 部署脚本所做的。

但是,如果你真的要检查是否存在,只有对象不存在才执行,从而避免错误,您可以编写一个 PL/SQL 块。写一个SQL检查用户是否存在,如果不存在,使用EXECUTE IMMEDIATEPL/SQL块做CREATE USER

这样的 PL/SQL 块的示例可能是:

declare
userexist integer;
begin
  select count(*) into userexist from dba_users where username='SMITH';
  if (userexist = 0) then
    execute immediate 'create user smith identified by smith';
  end if;
end;
/

从前面的回答可以看出,Oracle不支持if not exists。澄清在尝试创建一个已经存在的用户时 Oracle 会抛出哪些错误(作为奖励,在尝试删除一个不存在的用户时):

drop user foo;
ORA-01918: user 'foo' does not exist

create user existing_user IDENTIFIED BY existing_user;
ORA-01920: user name 'existing_user' conflicts with another user or role name

以上语句是在 Oracle Database 11g 企业版 11.2.0.1.0 版 - 64 位生产环境中执行的

另一种方法是在 PL/SQL 块中创建用户并捕获 ORA-01920 错误。这样,当用户存在时,该块不会抛出任何错误。

DECLARE
    sqlStatement varchar2(512);
    user_exists EXCEPTION;
    PRAGMA EXCEPTION_INIT(user_exists, -1920);
BEGIN
    sqlStatement := 'CREATE USER "Kyle" ' ||
       'IDENTIFIED BY "password" ' ||
       'PROFILE "Default" ' ||
       'ACCOUNT UNLOCK';
    EXECUTE IMMEDIATE sqlStatement;
    dbms_output.put_line('  OK: ' || sqlStatement);
EXCEPTION
   WHEN user_exists THEN
     dbms_output.put_line('WARN: ' || sqlStatement);
     dbms_output.put_line('Already exists');
   WHEN OTHERS THEN
     dbms_output.put_line('FAIL: ' || sqlStatement);
     RAISE;
END;
/