PL/SQL 触发器:无法创建顶级用户
PL/SQL trigger: can't create apex user
我正在处理数据库,剩下的最后一项任务是创建用户帐户。出于某种原因,我似乎无法让它工作。事实上,注释代码的 none 在未注释时有效。我们主要关心的是能够自动创建用户帐户,而不是手动创建它们。我希望有人可以阐明我的方法中的错误,以便我的代码能够编译。
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})', '() ');
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})', '() ');
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;
错误是
Compilation failed, line 6 (13:19:44) The line numbers associated with
compilation errors are relative to the first BEGIN statement. This
only affects the compilation of database triggers. PLS-00103:
Encountered the symbol "CREATE" when expecting one of the following: (
begin case declare else elsif end exit for goto if loop mod null
pragma raise return select update while with << continue
close current delete fetch lock insert open rollback savepoint set sql
execute commit forall merge pipe purge.
我已将方法更改为:
APEX_UTIL.CREATE_USER(
p_user_name => :new.USERNAME,
P_web_password => 'Password123');
现在它产生了这个错误:
An API call has been prohibited. Contact your administrator. Details
about this incident are available via debug id "46046".
Contact your application administrator.
您不能直接从 PLSQL 执行创建语句。
将其更改为:
IF INSERTING THEN
:NEW.SRN := seq_SRN.nextval;
execute immediate 'CREATE USER '||:new.USERNAME ||'
IDENTIFIED BY PASSWORD
PROFILE app_user
PASSWORD EXPIRE';
看起来很有趣,我正在回答我自己的问题,但我解决了这个问题。我用来创建 apex 用户的代码如下。
APEX_UTIL.CREATE_USER(
p_user_name => :new.USERNAME,
P_web_password => 'Password123',
p_change_password_on_first_use => 'Y');
上面的错误已通过更改应用程序构建器中的安全设置以允许 api 工作来解决,这是由以下内容发现的。
Application Builder -> (Your Application) -> Shared Components -> Security Attributes 最后在页面底部勾选 runtime API Usage 旁边的框,我根据需要勾选了所有 3 个。
您必须为自治事务设置触发器才能在触发器内提交。
CREATE TRIGGER your_trigger
BEFORE INSERT ON your_table FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
...
HTH
我正在处理数据库,剩下的最后一项任务是创建用户帐户。出于某种原因,我似乎无法让它工作。事实上,注释代码的 none 在未注释时有效。我们主要关心的是能够自动创建用户帐户,而不是手动创建它们。我希望有人可以阐明我的方法中的错误,以便我的代码能够编译。
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})', '() ');
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})', '() ');
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;
错误是
Compilation failed, line 6 (13:19:44) The line numbers associated with compilation errors are relative to the first BEGIN statement. This only affects the compilation of database triggers. PLS-00103: Encountered the symbol "CREATE" when expecting one of the following: ( begin case declare else elsif end exit for goto if loop mod null pragma raise return select update while with << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge.
我已将方法更改为:
APEX_UTIL.CREATE_USER(
p_user_name => :new.USERNAME,
P_web_password => 'Password123');
现在它产生了这个错误:
An API call has been prohibited. Contact your administrator. Details about this incident are available via debug id "46046".
Contact your application administrator.
您不能直接从 PLSQL 执行创建语句。
将其更改为:
IF INSERTING THEN
:NEW.SRN := seq_SRN.nextval;
execute immediate 'CREATE USER '||:new.USERNAME ||'
IDENTIFIED BY PASSWORD
PROFILE app_user
PASSWORD EXPIRE';
看起来很有趣,我正在回答我自己的问题,但我解决了这个问题。我用来创建 apex 用户的代码如下。
APEX_UTIL.CREATE_USER(
p_user_name => :new.USERNAME,
P_web_password => 'Password123',
p_change_password_on_first_use => 'Y');
上面的错误已通过更改应用程序构建器中的安全设置以允许 api 工作来解决,这是由以下内容发现的。 Application Builder -> (Your Application) -> Shared Components -> Security Attributes 最后在页面底部勾选 runtime API Usage 旁边的框,我根据需要勾选了所有 3 个。
您必须为自治事务设置触发器才能在触发器内提交。
CREATE TRIGGER your_trigger
BEFORE INSERT ON your_table FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
...
HTH