PL / SQL触发器:无法创建顶点用户

时间:2015-11-06 13:21:09

标签: sql database oracle plsql oracle-apex

我正在开发一个数据库,剩下的最后一项任务就是创建用户帐户。出于某种原因,我似乎无法让它发挥作用。事实上,没有评论的代码在取消注释时有效。我们主要关心的是能够自动创建用户帐户而不是手动创建它们。我希望有人可以解释我的方式错误,以便我的代码编译。

create or replace TRIGGER trg_Students
BEFORE INSERT OR UPDATE OF SRN, Surname, Forename, Username, DOB, Date_Cv_Submitted, Date_cv_approved, same_address, home_phone_no, home_postcode ON Students 
FOR EACH ROW
BEGIN

IF INSERTING THEN
   :NEW.SRN := seq_SRN.nextval;

   CREATE USER :new.USERNAME
   IDENTIFIED BY PASSWORD
   PROFILE app_user
   PASSWORD EXPIRE;

    --IF (ACTIVE_ACCOUNT = 'Y' AND CV_APPROVED = NULL) THEN
    --    RAISE_APPLICATION_ERROR(-20000, 'Cannot create an account that is active before the cv is approved!');
    --END IF;        

END IF; 

--IF UPDATING THEN
    --IF (DATE_CV_APPROVED != NULL) THEN
    --:new.Active_Account := 'Y';
    --END IF;
--END IF;

:NEW.forename := INITCAP(:NEW.forename);
:NEW.surname := INITCAP(:NEW.surname);

:NEW.home_postcode := UPPER(:NEW.home_postcode);

:NEW.home_phone_no := REGEXP_REPLACE(:NEW.home_phone_no, '[^[:digit:]]', '');
:NEW.home_phone_no := REGEXP_REPLACE(:NEW.home_phone_no,
                   '([[:digit:]]{5})([[:digit:]]{6})', '(\1) \2');


IF :NEW.same_address = 'Y' THEN
:NEW.term_no := :NEW.home_no;
:NEW.term_postcode := :NEW.home_postcode;
:NEW.term_phone_no := :NEW.home_phone_no;
ELSE
:NEW.term_postcode := UPPER(:NEW.term_postcode);
:NEW.term_phone_no := REGEXP_REPLACE(:NEW.term_phone_no, '[^[:digit:]]', '');
:NEW.term_phone_no := REGEXP_REPLACE(:NEW.term_phone_no,
                   '([[:digit:]]{5})([[:digit:]]{6})', '(\1) \2');
END IF;


IF (:NEW.DOB + NUMTOYMINTERVAL(18,'YEAR') > SYSDATE) THEN
    RAISE_APPLICATION_ERROR(-20000, 'Client must be at least 18 years of age!');
END IF;

IF (:NEW.Date_cv_approved < :NEW.date_cv_submitted) THEN
    RAISE_APPLICATION_ERROR(-20000, 'Cannot approve a cv before it is submitted!');
END IF; 

END;

错误是

  

编译失败,第6行(13:19:44)与之关联的行号   编译错误与第一个BEGIN语句有关。这个   仅影响数据库触发器的编译。 PLS-00103:   遇到了符号&#34; CREATE&#34;当期待以下之一:   如果循环mod为null,则开始case声明else elsif end exit for goto   使用&lt;&lt;时,pragma raise返回选择更新继续   close current delete fetch lock insert open rollback savepoint set sql   执行commit forall merge pipe purge。

我已将方法更改为:

   APEX_UTIL.CREATE_USER(
   p_user_name => :new.USERNAME,
   P_web_password => 'Password123');

现在它产生了这个错误:

  

禁止使用API​​调用。联系您的管理员。细节   关于此事件可通过调试ID&#34; 46046&#34;。

获得      

与您的应用程序管理员联系。

3 个答案:

答案 0 :(得分:3)

您无法直接从PLSQL执行create语句。

将其更改为:

IF INSERTING THEN
   :NEW.SRN := seq_SRN.nextval;

   execute immediate 'CREATE USER '||:new.USERNAME ||'
                      IDENTIFIED BY PASSWORD
                      PROFILE app_user
                      PASSWORD EXPIRE';

答案 1 :(得分:2)

似乎很有趣,我正在回答我自己的问题,但我解决了这个问题。我用来创建apex用户的代码如下。

   APEX_UTIL.CREATE_USER(
   p_user_name => :new.USERNAME,
   P_web_password => 'Password123',
   p_change_password_on_first_use => 'Y');

通过更改应用程序构建器中的安全设置以允许api工作,可以解决上述错误,如下所示。 Application Builder - &gt; (您的申请) - &gt;共享组件 - &gt;安全属性,最后勾选页面底部运行时API使用旁边的框,我按需要勾选所有3个。

答案 2 :(得分:0)

您必须为自治事务设置触发器才能在触发器内提交。

CREATE TRIGGER your_trigger
   BEFORE INSERT ON your_table FOR EACH ROW
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
...

HTH