情况:有一个 java 应用程序从 DB Oracle 读取数据。为了简化,电子邮件字段当前是从“USERS”表中读取的。现在我必须修改应用程序,以便可以读取更多电子邮件地址,但我无意修改引用此表的所有数十个现有查询。欺骗行为是添加一个“EMAILS”表,其中(除了 PK“id_mailaddr”之外)仅包含“id_user”和“mail_address”字段。但因为数据不仅由应用程序加载,还由其他用户通过最多样化的方法(Excel 表、查询“插入全部”、sql 加载器等)加载,我必须在数据库级别强加一致性条件。问题就在这里!我不知道Oracle和PL-sql。如何编写“检查”约束来强加这样的约束:如果我在新表中插入的电子邮件地址的“id_user”已经存在于“USERS”表中,则该“id_user”在表“USERS”中匹配的电子邮件地址必须与新表中匹配的电子邮件地址一致?
例如:
USERS EMAILS
id_user user email id_mailaddr id_user mail_address
100 Smith smith@yahoo.com 1 100 smith@yahoo.com OK!
101 Brown brown@gmail.com 2 101 brown@gmail.com OK!
102 M.Scott 3 105 scott@hotmail.com NO!
103 J.Scott scott@hotmail.com 4 103 j_scott@hotmail.com NO!
104 P.Scott 5 104 scotty@aol.com OK!
最佳答案
希望这个触发代码有帮助 -
drop table users;
drop table email;
CREATE TABLE users
(id_user integer, userz varchar2(7), email varchar2(17))
;
INSERT ALL
INTO users (id_user, userz, email)
VALUES (100, 'Smith', 'smith@yahoo.com')
INTO users (id_user, userz, email)
VALUES (101, 'Brown', 'brown@gmail.com')
INTO users (id_user, userz, email)
VALUES (102, 'M.Scott', '')
INTO users (id_user, userz, email)
VALUES (103, 'J.Scott', 'scott@hotmail.com')
INTO users (id_user, userz, email)
VALUES (104, 'P.Scott', '')
SELECT * FROM dual
;
CREATE TABLE email
(id_mailaddr int, id_user int, mail_address varchar2(19))
;
insert INTO email (id_mailaddr, id_user, mail_address)
VALUES (3, 105, 'scott@hotmail.com');
insert INTO email (id_mailaddr, id_user, mail_address)
VALUES (5, 104, 'scotty@aol.com');
create or replace trigger email_trig
after insert on email
for each row
declare
v_cnt integer := 0;
mail_adr varchar2(64);
e exception;
begin
if inserting then
select email, count(*) into mail_adr, v_cnt from users where id_user = :new.id_user group by email;
if v_cnt = 0 or mail_adr <> :new.mail_address then
raise e;
end if;
end if;
exception
when others then
raise_application_error(-20000, 'Error inserting new email:- '||:new.mail_address);
end;
/
关于java - 检查约束(或更好的东西),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51198913/