【问题标题】:Parameters on Execute Immediate Sentence (Inside a procedure)执行立即语句的参数(在过程中)
【发布时间】:2013-05-24 14:30:56
【问题描述】:

我正在尝试从我的用户表在一个过程中创建一个 ORACLE USER。问题是我不知道如何调用特定列。我已经尝试过 Camp.user.username 之类的东西。

create or replace 
PROCEDURE PR_USERPASS AS
 BEGIN
  UPDATE CAMP.USERS
  SET USERNAME = (DBMS_RANDOM.string('x',15)), PASS = DBMS_RANDOM.string('x',12);
  EXECUTE IMMEDIATE 'CREATE USER ' || USERNAME || ' IDENTIFIED BY ' || PASSWORD;
  EXECUTE IMMEDIATE 'Grant connect to ' || USERNAME;
 END PR_USERPASS;

有没有在同一个过程中调用这些引用? 提前谢谢你。

【问题讨论】:

    标签: oracle oracle11g createuser execute-immediate


    【解决方案1】:

    使用cursor 循环访问Camp.Users 表并访问其列。你的代码会是这样的(未经测试):

    create or replace 
    PROCEDURE PR_USERPASS AS
    BEGIN
      UPDATE CAMP.USERS
      SET USERNAME = (DBMS_RANDOM.string('u',15)), PASS = DBMS_RANDOM.string('x',12);
      FOR userRow IN (SELECT Username, Pass FROM Camp.Users) LOOP
         EXECUTE IMMEDIATE 'CREATE USER ' || userRow.Username || ' IDENTIFIED BY ' || userRow.Pass;
         EXECUTE IMMEDIATE 'GRANT CONNECT TO ' || userRow.Username;
      END LOOP;
    END PR_USERPASS;
    

    附录:原始答案生成USERNAMEDBMS_Random.String('x', 15),它允许用户名和密码使用数字和数字。当用户名以数字开头时,这会引起麻烦。答案已更改为使用 DBMS_Random.String('u', 15) 仅生成 Oracle 可接受的用户名值。密码开头的数字似乎没问题。

    如果需要以数字开头的用户名,只需将用户名用双引号括起来即可:

         EXECUTE IMMEDIATE 'CREATE USER "' || userRow.Username || '" IDENTIFIED BY ' || userRow.Pass;
         EXECUTE IMMEDIATE 'GRANT CONNECT TO "' || userRow.Username || '"';
    

    也就是说,我不确定使用非标准用户名是否是个好主意。

    DBMS_Random.String 的文档可以在 here 找到。

    【讨论】:

    • 我试过 EXECUTE IMMEDIATE 'CREATE USER (:a) IDENTIFIED BY (:b)' USING userRow.USERNAME, userRow.PASS;还是不行。
    • ORA-01935 错误吗?在这种情况下,可能是因为DBMS_Random.String('x', length) 返回一个包含字母和数字的值,如果第一个字符是数字,则它不是用户名或密码的有效名称。您想要以数字开头的用户名或密码吗?无论哪种方式都可以;请告诉我,我会发布更新。
    • 你是对的!我在 DBMS_RANDOM 中将 'x' 更改为 'u',现在它可以工作了。无论如何,您知道如何使用以数字开头的密码吗?谢谢大家!
    • 我只是在这里尝试过,Oracle让我创建一个密码为123456的用户,所以当我说开头有数字的密码无效时我错了。您应该能够使用DBMS_Random.String('x', 12) 获取密码。也就是说,如果您遇到任何问题,只需将密码用双引号括起来:... IDENTIFIED BY "' || userRow.Pass || '"';。使用双引号,您可以摆脱 any 值。
    • 另请注意,双引号除了允许您使用非标准字符(包括标点符号和空格)外,还会使值区分大小写。很多人(包括我)都遇到了麻烦:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多