【问题标题】:Create user from string variables in a PL/SQL block从 PL/SQL 块中的字符串变量创建用户
【发布时间】:2016-02-17 08:12:31
【问题描述】:

我使用 Oracle XE 的唯一目的是开发 PHP 应用程序,而 11g 版本显然失去了 10g 曾经拥有的用于管理用户的 GUI 工具,所以我想准备一个代码 sn-p 来从命令行创建用户.我正在尝试define variables,所以我不需要输入相同的用户名 16 次,但我无法正确使用语法:

DECLARE
    my_user VARCHAR2(30) := 'foo';
    my_password VARCHAR2(9) := '1234';
BEGIN
    CREATE USER my_user IDENTIFIED BY my_password DEFAULT TABLESPACE users;

    GRANT CONNECT, RESOURCE TO my_user;
    GRANT CREATE DATABASE LINK TO my_user;
    GRANT CREATE MATERIALIZED VIEW TO my_user;
    GRANT CREATE PROCEDURE TO my_user;
    GRANT CREATE PUBLIC SYNONYM TO my_user;
    GRANT CREATE ROLE TO my_user;
    GRANT CREATE SEQUENCE TO my_user;
    GRANT CREATE SYNONYM TO my_user;
    GRANT CREATE TABLE TO my_user;
    GRANT CREATE TRIGGER TO my_user;
    GRANT CREATE TYPE TO my_user;
    GRANT CREATE VIEW TO my_user;

    GRANT SELECT_CATALOG_ROLE TO my_user;
    GRANT SELECT ANY DICTIONARY TO my_user;
END;
/
        CREATE USER my_user IDENTIFIED BY my_password DEFAULT TABLESPACE users;
        *
ERROR en línea 5:
ORA-06550: line 5, column 2:
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge

是否禁止在 PL/SQL 块中使用 CREATE USER 语句,或者我只是犯了一个愚蠢的错字?是否必须使用 SQL*Plus 变量?

【问题讨论】:

    标签: oracle plsql oracle11g ddl oracle-xe


    【解决方案1】:

    PLS-00103:在预期以下情况之一时遇到符号“CREATE”:

    上述错误是因为您在 PL/SQL 中使用了 DDL。你不能这样做。您必须(ab)使用 EXECUTE IMMEDIATEPL/SQL 中发出 DDL 语句

    例如,

    SQL> DECLARE
      2    my_user     VARCHAR2(30) := 'foo';
      3    my_password VARCHAR2(9)  := '1234';
      4  BEGIN
      5    EXECUTE IMMEDIATE 'CREATE USER '||my_user||' IDENTIFIED BY '||my_password;
      6    EXECUTE IMMEDIATE 'GRANT CREATE SESSION TO '||my_user;
      7  END;
      8  /
    
    PL/SQL procedure successfully completed.
    
    SQL> conn foo/1234@pdborcl
    Connected.
    SQL> SHOW USER
    USER is "FOO"
    

    来自documentation的快速参考,

    在 PL/SQL 中执行 DDL 和 SCL 语句

    只有动态SQL可以执行以下类型的语句 在 PL/SQL 程序单元内:

    • 数据定义语言 (DDL) 语句,例如CREATEDROPGRANTREVOKE

    • 会话控制语言 (SCL) 语句,例如ALTER SESSIONSET ROLE

    • SELECT 语句中的TABLE 子句

    顺便说一句,

    创建用户和授予权限通常是由 DBA 负责的数据库管理任务。这不是通过 PL/SQL 程序完成的频繁活动。 DBA 作为一次性活动创建用户并授予必要的权限。

    【讨论】:

    • 响亮清晰,非常感谢。我想这有助于解释为什么 SQL*Plus 变量如此受欢迎。
    • @ÁlvaroGonzález 不客气!请注意,这些是数据库管理任务,通常不通过 PL/SQL 程序完成。您只创建一次用户并授予权限一次。 DBA 需要这样做,通常不是 PL/SQL 开发人员。我不知道你的确切要求,所以你可能有一个用例来这样做;-)
    • 我的确切要求是镇上没有 DBA 但我仍然需要 Oracle ;-)
    • @ÁlvaroGonzález LOL,祝你好运。我更喜欢 SQL*Plus 脚本,一次声明变量并在整个脚本中使用它们。您可以将整个 DDL 放在 .sql 文件中,并将变量作为参数传递。请将其标记为已回答,对他人有帮助。
    • 我想强调一下,因为这些话中没有提到,所以根据这个 PL/SQL 代码所在的位置创建这样的用户是有安全风险的。如果代码是一次性代码,只有在您运行 DBA 任务时才能访问,那么这应该没问题。但是,如果此代码是某个应用程序的一部分,并且是通过调用某些例程调用链以编程方式运行的……这是非常危险的。可能存在带有my_usermy_password 的SQL 注入,或者只是不需要的用户创建。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 2018-06-08
    • 1970-01-01
    相关资源
    最近更新 更多