아니, 정확하게이 작업을 수행 할 수 없습니다.
트리거 내에서 커밋 할 수 없습니다 (일반적으로 아래 예외에 대해 설명합니다). CREATE USER
과 같은 DDL은 DDL을 트리거에 넣을 수 없도록 두 개의 암시 적 커밋 (문 앞에 하나와 문 뒤에 하나)을 발행합니다.
자율 트랜잭션을 사용하도록 트리거를 선언하면 트리거 내부 커밋에 대한 규칙의 예외가 발생합니다. 그러나 이것은 몇 가지 이유로 문제를 올바르게 해결하지 못합니다. 먼저, 자율 트랜잭션은 이름에서 알 수 있듯이 자율적이므로 트리거하는 명령문이 롤백 되더라도 커밋됩니다. 즉, INSERT
문이 행을 성공적으로 삽입했지만 해당 변경 사항이 롤백되면 자치 트랜잭션이 커밋 된 상태로 유지되므로 사용자가 생성되지만 결국 plsql_test_users
테이블에 행이 없습니다. 쓰기 일관성을 위해 Oracle은 내부적으로 두 번 실행되는 명령문을 내부적으로 롤백하고 다시 실행할 수 있습니다.이 명령문은 사용자가 이미 존재하기 때문에 실패합니다. 자발적 트랜잭션은 실제로 기본 변경 작업이 성공했는지 여부에 관계없이 정보를 기록하려는 경우에만 사용해야합니다 (예 : 로그인 시도 또는 로그인 변경 시도로 로그인 또는 비밀번호 변경 실패로 인해 공격을 탐지 할 수 있습니다. 데이터의 상태).
dbms_job.submit
트리거를 호출하여 명령문이 커밋 된 후 곧 실행되는 백그라운드 작업을 제출하여 실제로 사용자를 생성 할 수 있습니다. 테이블에 추가되는 행과 생성되는 사용자 사이에 약간의 지연이 발생하지만 적어도 트랜잭션 적으로는 정확합니다 (생성하려는 사용자의 수와 백그라운드의 수와 같은 요소에 따라 지연이 커질 수 있습니다. 허용하는 작업). 아쉽게도 최신 dbms_scheduler
패키지 대신 이전 dbms_job
패키지를 사용해야합니다. 최신 패키지에 암시 적 커밋이 포함되어 있기 때문에 작업을 제출해야합니다.
백그라운드 작업 경로를 종료 한 경우 EXECUTE IMMEDIATE
에 전달 된 명령문은 동적 SQL 문 실행시 해당 변수가 범위에 있지 않은 로컬 변수의 값을 참조 할 수 없습니다. 당신이
EXECUTE IMMEDIATE 'CREATE USER n IDENTIFIED BY p';
n
및 p
당신이 정의한 지역 변수를 참조하지 않는 쓸 때, 그들은 문자 그대로의 식별자입니다. 이렇게하면 단일 문자 암호 "p"로 사용자 "n"이 생성됩니다. 테이블의 사용자 이름과 암호를 사용하려는 경우 동적 SQL 문을 어셈블하는 동안이를 사용해야합니다. 뭔가 같은 것
EXECUTE IMMEDIATE
'CREATE USER ' || :new.name ||
' IDENTIFIED BY ' || :new.password;
그리고이 모든 것이 왜 두 곳에서 정보를 저장하려고하는지 궁금해합니다. 오라클 사용자이기도 한 많은 사용자 이름 & 암호를 가진 테이블 plsql_test_users
을 갖고 싶지는 않을 것 같습니다.오라클이 인증을 처리하기를 원하거나 애플리케이션이 인증을 처리하도록하려는 경우 각각이 인증을 처리한다고 생각하지 않아도됩니다 (예를 들어, 비밀번호가 변경되면 어떻게되는지). 응용 프로그램이 인증을 처리하려면 암호 (또는 암호화 된 암호)를 저장하지 마십시오. RAW 열에 소금으로 암호 해시를 저장합니다. 그런 다음 사용자가 로그인 할 때 암호를 제공하고 해시를 비교할 때 해시를 계산하고 확인합니다.