Oracle 我可以创建一个触发器来创建一个新用户吗?

Oracle 我可以创建一个触发器来创建一个新用户吗?,oracle,triggers,Oracle,Triggers,如果可能的话。。。你怎么能这么做?我是数据库新手,请帮帮我! 我使用的是oracle,当我在表“users”中插入新行时,我想创建一个新用户,正如JGreenwell提到的,是的,您可以这样做,但这不是一个好主意。主要问题不是密码不清晰,而是事务性的副作用 让我们以清晰的方式查看密码解决方案: 很容易解决密码的问题(不要将密码存储在clear中、加密或散列)。如果您已经安装了DMBS_CRYPTO并对其拥有权限,那么您可以创建一个过程(我假设您有一个表,其中包含to列:USERNAME和USER

如果可能的话。。。你怎么能这么做?我是数据库新手,请帮帮我!
我使用的是oracle,当我在表“users”中插入新行时,我想创建一个新用户,正如JGreenwell提到的,是的,您可以这样做,但这不是一个好主意。主要问题不是密码不清晰,而是事务性的副作用

让我们以清晰的方式查看密码解决方案:

很容易解决密码的问题(不要将密码存储在clear中、加密或散列)。如果您已经安装了DMBS_CRYPTO并对其拥有权限,那么您可以创建一个过程(我假设您有一个表,其中包含to列:USERNAME和USERPASS):

和一个触发器:

CREATE OR REPLACE TRIGGER TUSERS BEFORE INSERT ON USERS FOR EACH ROW
BEGIN
    MYCREATEUSER(:NEW.USERNAME, :NEW.USERPASS);
    :NEW.USERPASS := DBMS_CRYPTO.HASH(:NEW.USERPASS, DBMS_CRYPTO.HASH_SH1);
END;
insert语句使用用户名和密码,触发器创建用户,但在插入行之前,它会用SHA1哈希值替换密码。查询表时必须记住这一点

一个例子:

INSERT INTO USERS VALUES('Mary', 'Mary123');
检查:

SELECT COUNT(*) 
  FROM USERS 
  WHERE USERNAME = 'Mary' AND 
        USERPASS = DBMS_CRYPTO.HASH('Mary123', DBMS_CRYPTO.HASH_SH1);
如果count=1,则用户和密码存在,但如果count=0,则用户/密码不存在

此示例仅在以下情况下有效:您已安装DBMS_CRYPTO并具有足够的权限,并且具有创建表权限(请记住,当一个过程执行语句时,它只有显式授予的特权,来自角色的特权被禁用-因此,拥有资源特权是不够的,您需要创建表显式特权)

但正如我所提到的,这不是一个好主意,因为您可能会受到事务性副作用的影响。让我们看看主要问题:

保持酸性原则(原子性、一致性、隔离性和耐久性)Oracle需要确保将一条语句视为原子操作。如果执行INSERT INTO USERS SELECT*FROM OTHER_USER_表,则此语句必须视为原子单元。原子单元在您发送语句时开始,在Oracle通知您错误/ok代码时结束

但是触发器在语句内部执行(在其时间范围内)。触发器控制insert语句(如果它失败,则所有语句都失败,如果它说ok,则语句是ok)。请注意,该语句在触发器完成后结束。这意味着在该语句结束之前无法提交或回滚当前事务(因为在这种情况下无法确保原子性)。因此,触发器无法提交/回滚当前事务(它不能提交,也不能调用过程来提交,在语句结束之前,没有人可以这样做)。 CREATETABLE是一个自动提交语句(如果强制提交),因此无法在触发器范围内创建表

但我们说“你可以”,我们有一个有效的例子。如何? 答案是PRAGMA自治事务。 这个pragma强制oracle在一个新的不同事务中执行受影响的PL/SQL块

Oracle没有嵌套的事务模型,因此内部自治_事务不依赖于外部触发器的事务。它们都是平面事务。这意味着,如果过程结束(用户被创建)并且插入最终失败(由于任何原因),则行不在表中,但新用户存在

让我们看一个例子:

INSERT INTO USERS VALUES ('Anne', 'An232131');
INSERT INTO USERS VALUES ('Mike', "ABC123');
ROLLBACK;
此示例插入两行(它创建两个用户)并回滚事务。因此,最后将取消插入,并且这些行(Anne an Mike)不在用户表中。但是Anne和Mike Oracle的用户存在(回滚)不会影响用户创建,因为它们是由最终提交的不同事务创建的(自主交易)


如果没有嵌套事务模型,这个问题不容易解决(在嵌套事务模型中,内部事务只有在外部事务提交时才最终提交)如果你把你尝试过的和你有问题的地方放在一起,你可能会得到更好的回答。但是回答你的问题:这不是正确的方法。你应该考虑一个存储过程来创建一个用户,它在完成时将一个记录插入到表中。在clear中(如@JGreenwell链接到的解决方案中),这是一个坏消息idea@apc该链接中的评论中提到了该密码。感谢您更清楚地说明
INSERT INTO USERS VALUES ('Anne', 'An232131');
INSERT INTO USERS VALUES ('Mike', "ABC123');
ROLLBACK;