执行立即语句的参数(在过程中)

Posted

技术标签:

【中文标题】执行立即语句的参数(在过程中)【英文标题】: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;

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

【问题讨论】:

【参考方案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 值。 另请注意,双引号除了允许您使用非标准字符(包括标点符号和空格)外,还会使值区分大小写。很多人(包括我)都遇到了麻烦:)

以上是关于执行立即语句的参数(在过程中)的主要内容,如果未能解决你的问题,请参考以下文章

如何将表名分配给变量并在立即执行语句中使用相同的

关于在存储过程中立即执行

动态调用存储过程(立即执行)输出参数问题

ACL执行过程

PL/SQL中测试存储过程,如何立即输出DBMS_OUTPUT的语句。

mysql之sql语句执行过程