执行立即语句的参数(在过程中)
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;
附录:原始答案生成USERNAME
为DBMS_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 值。
另请注意,双引号除了允许您使用非标准字符(包括标点符号和空格)外,还会使值区分大小写。很多人(包括我)都遇到了麻烦:)以上是关于执行立即语句的参数(在过程中)的主要内容,如果未能解决你的问题,请参考以下文章