我正在研究数据库的简单功能。
当用户注册我的应用程序时,字段password_changed
初始化为0,在我的user trigger
中执行此操作后,我想触发以下方法向该新用户发送一条消息告诉他们他们应该更新密码。
CREATE OR REPLACE TRIGGER trg_users
BEFORE INSERT OR UPDATE ON users FOR EACH ROW
BEGIN
-- Get the new user id
IF :NEW.user_id IS NULL THEN
SELECT seq_user_id.nextval
INTO :NEW.user_id
FROM sys.dual;
END IF;
-- Alert a user that they need to change their password
IF :NEW.pass_changed IS NULL THEN
:NEW.pass_changed := 0;
send_alert(:NEW.user_id, 'Thank-you for registering, please change your password for security reasons!');
END IF;
END;
这个第一个触发器只是初始化设置为0
的密码,然后调用我的send_alert()函数,获取由我的序列填充的:NEW.user_id
。
send_alert()程序:
-- Sends an alert to the user noting that they haven't changed their password
CREATE OR REPLACE PROCEDURE send_alert(
this_user users.user_id%TYPE,
this_message STRING
)
AS
BEGIN
INSERT INTO messages
VALUES('', this_user, getSystemId(), 'ALERT', this_message, '', '');
END send_alert;
当此代码运行时,我收到错误integrity constraint (PRCSE.INBOX_MESSAGE_TO_FK) violated - parent key not found
我理解这意味着什么 - 但是如果我用该字段替换现有值,则应通过this_user
填充父键的值。程序完成,旧用户INSERTS
。
我只能认为由于某种原因:NEW.user_id
没有通过,但我在调用我的程序之前初始化它的值。
EDIT 10/04/14 13:48 GMT :要清除任何混淆,getSystem()会返回主管理员ID
-- Gets the ID of the SYSTEM user via its unique email
CREATE OR REPLACE FUNCTION getSystemId
RETURN NUMBER
IS
system_user users.user_id%TYPE;
pragma autonomous_transaction;
BEGIN
SELECT user_id
INTO system_user
FROM users
WHERE user_email = 'system@application.com'
AND user_permissions = 'ADMIN';
RETURN system_user;
COMMIT;
END getSystemId;
任何帮助将不胜感激 - 此致,Alex。
答案 0 :(得分:2)
这是因为您尝试在BEFORE触发器中插入值(例如,在插入父行之前):
SQL> create table t(x int primary key);
SQL> create table t_c(x int references t(x));
SQL> create or replace trigger tr_i
2 before insert on t
3 for each row
4 begin
5 insert into t_c(x) values(:new.x);
6 end;
7 /
SQL> insert into t values(1);
insert into t values(1)
*
error in line 1:
ORA-02291: integrity constraint (SCOTT.SYS_C00330529) voilated - parent key not found
ORA-06512: in "SCOTT.TR_I", line 2
ORA-04088: error in trigger execution 'SCOTT.TR_I'
SQL> create or replace trigger tr_i
2 after insert on t
3 for each row
4 begin
5 insert into t_c(x) values(:new.x);
6 end;
7 /
SQL> insert into t values(1);
1 row inserted.
SQL> select * from t;
X
------
1
SQL> select * from t_c;
X
------
1