Postgresql 9.2.24 문서화 | ||||
---|---|---|---|---|
PostgreSQL: Tài liệu: 9.2: Lỗi và tin 토토 사이트 | up | 39 장.pl/pgsql - SQL절차 언어 | 다음 |
pl/pgsql익숙해 질 수 있습니다 와이즈 토토 절차를 정의하십시오. 와이즈 토토 절차가 생성됩니다 그만큼기능 만들기명령, 선언 인수가없는 함수와 반환 유형의 함수와이즈 토토. 함수는 있어야합니다 받을 것으로 예상 되더라도 논쟁없이 선언 지정된 인수와이즈 토토 만들기- 와이즈 토토 인수는를 통해 전달됩니다.TG_ARGV, 아래 설명대로.
apl/pgsql함수는입니다 와이즈 토토라고 불리는 몇 가지 특수 변수가 생성됩니다 최상위 블록에서 자동으로. 그들은 :
데이터 유형레코드; 가변 보유 새로운 데이터베이스 행삽입/업데이트행 수준 와이즈 토토의 작동. 이 변수는NULL명령문 수준 와이즈 토토 그리고 for삭제운영.
데이터 유형레코드; 가변 보유 기존 데이터베이스 행업데이트/삭제로드 레벨 와이즈 토토의 작동. 이 변수는NULL명령문 수준 와이즈 토토 그리고 for삽입운영.
데이터 유형이름; 변수 실제로 해고 된 방아쇠의 이름이 포함되어 있습니다.
데이터 유형텍스트; 문자열전, 이후또는대신 의12894_12936
데이터 유형텍스트; 둘 중 하나row또는진술방아쇠에 따라 정의.
데이터 유형텍스트; 문자열삽입, 업데이트, 삭제또는Truncate작동 방아쇠가 발사되었습니다.
데이터 유형OID; 객체 ID 와이즈 토토 호출을 일으킨 테이블
데이터 유형이름; 이름의 이름 와이즈 토토 호출을 일으킨 테이블. 이것은 지금입니다 더 이상 사용되지 않았으며 향후 릴리스에서 사라질 수 있습니다. 사용tg_table_name대신.
데이터 유형이름; 이름의 이름 와이즈 토토 호출을 일으킨 테이블
데이터 유형이름; 이름의 이름 와이즈 토토 호출을 일으킨 테이블 스키마
데이터 유형정수; 수 의 와이즈 토토 절차에 대한 인수와이즈 토토 만들기진술.
데이터 유형 배열텍스트; 그만큼 의 논쟁와이즈 토토 만들기진술. 인덱스는 0. 유효하지 않은 인덱스에서 카운트합니다 (낮음 0 이상 또는보다tg_nargs) null 값을 초래합니다.
와이즈 토토 함수는 어느 쪽이든 반환해야합니다null또는 정확히 값을 가진 레코드/행 값 테이블의 구조 와이즈 토토가 발사되었습니다.
로드 레벨 와이즈 토토 발사전can NULL을 반환하여 와이즈 토토 관리자에게 나머지 부분을 건너 뛰도록 신호를 보냅니다. 이 행의 작업 (즉, 후속 와이즈 토토가 발사되지 않음 그리고삽입/업데이트/삭제그렇지 않습니다 이 행에 발생합니다). unnull 값이 반환되면 작업은 해당 행 값을 진행합니다. 행 값을 반환합니다 원래 값과 다르NEW삽입 또는 업데이트 될 행을 변경합니다. 따라서 와이즈 토토 함수는 와이즈 토토링 작업이 정상적으로 성공하기를 원합니다 행 값을 변경하지 않고NEW(또는 동일한 값이 반환되어야합니다. 행을 변경하려면 저장, 직접 단일 값을 대체 할 수 있습니다NEW수정 된 반환NEW또는 완전한 새 레코드/행을 구축합니다 반품. 전 와이즈 토토의 경우삭제, 반환 된 값은 직접적인 영향을 미치지 않습니다. 그러나 와이즈 토토 조치가 진행되도록하려면 unnull이어야합니다. 참고NEW삭제와이즈 토토, 따라서 반환하는 것은 일반적으로 그렇지 않습니다 현명한. 일반적인 관용구삭제와이즈 토토는 반환됩니다old.
대신와이즈 토토 (항상 로드 레벨 와이즈 토토, 뷰에서만 사용될 수 있음) 반환 할 수 있습니다. 그들이 업데이트를 수행하지 않았다는 신호를 보내고 이 행의 나머지 작업을 건너 뛰어야합니다 (예 : 후속 와이즈 토토는 발사되지 않으며 행이 계산되지 않습니다. 주변의 줄에 영향을받는 상태삽입/업데이트/삭제). 그렇지 않으면 unnull이 아닌 값이 있어야합니다 반환, 와이즈 토토가 요청 된 것을 수행했음을 알리기 위해 반품 작업. 을 위한삽입and업데이트운영, 반환 값은이어야합니다.NEW, 와이즈 토토 함수가있을 수 있습니다 지원하기 위해 수정리턴 삽입and업데이트 반환(이것은 또한 영향을 미칩니다 행 값은 후속 와이즈 토토로 전달되었습니다). 을 위한삭제운영, 반환 값은old.
로드 레벨 와이즈 토토의 반환 값이 발사되었습니다이후또는 명세서 수준 와이즈 토토 발사전또는이후항상 무시됩니다. 그것은 널가 될 수도 있습니다. 그러나 어떤 것도 이러한 유형의 와이즈 토토는 여전히 전체 작업을 중단 할 수 있습니다. 오류 제기.
예제 39-3와이즈 토토 프로 시저의 예를 보여줍니다pl/pgsql.
예 39-3. 에이pl/pgsql와이즈 토토 프로 시저
이 예제 와이즈 토토는 행이 삽입 될 때마다 또는 테이블에서 업데이트 된 현재 사용자 이름과 시간은 줄에 찍혔습니다. 그리고 직원의 이름이 있는지 확인합니다 주어지고 급여는 긍정적 인 가치입니다.
Table Emp 만들기 ( Empname 텍스트, 급여 정수, last_date timestamp, last_user 텍스트 ); function emp_stamp ()를 $ emp_stamp $로 와이즈 토토로 반환합니다 시작하다 - empname과 월급이 주어 졌는지 확인하십시오 new.empname이 null이라면 그렇다면 'empname은 null이 될 수 없다'는 예외를 높이십시오. 끝 IF; New.salary가 null이라면 '%는'%가 널 급여를 가질 수 없다 ', new.empname; 끝 IF; - 그녀가 돈을 지불해야 할 때 누가 우리를 위해 일합니까? 새로운.salary <0이라면 '%는'%가 부정적인 급여를 가질 수 없습니다 ', new.empname; 끝 IF; - 누가 급여를 바꾸 었는지 기억하십시오 new.last_date : = current_timestamp; new.last_user : = current_user; 새로운 반환; 끝; $ emp_stamp $ language plpgsql; EMP에 삽입하거나 업데이트하기 전에 Trigger Emp_stamp를 만듭니다 각 행에 대해 Execute Procedure Emp_stamp ();
테이블에 로그 변경하는 또 다른 방법은 새로운 것을 만드는 것과 관련이 있습니다. 각 삽입, 업데이트 또는 삭제에 대해 행을 보유하는 테이블 발생합니다. 이 접근법은 감사 변경으로 생각할 수 있습니다. 테이블.예 39-4감사 와이즈 토토 절차의 예를 보여줍니다pl/pgsql.
예 39-4. 에이pl/pgsql와이즈 토토 절차 감사
이 예제 와이즈 토토는 삽입, 업데이트 또는 에서 행 삭제emp테이블은 기록 된 (즉, 감사)emp_audit테이블. 현재 시간과 사용자 이름 작업 유형과 함께 행에 스탬핑됩니다. 그것에 대해 수행했습니다.
Table Emp 만들기 ( embname 텍스트가 null, 급여 정수 ); 테이블 작성 emp_audit ( char (1) null이 아닌 작전, 스탬프 타임 스탬프가 널 있지 않음, userID 텍스트는 null이 아닙니다. embname 텍스트가 null, 급여 정수 ); 함수 process_emp_audit ()를 $ emp_audit $로 반환합니다 시작하다 - - EMP에서 수행 된 작업을 반영하기 위해 EMP_AUDIT에서 행을 만듭니다. - 특수 변수 TG_OP를 사용하여 작업을 수행하십시오. - if (tg_op = 'delete') 그러면 emp_audit에 삽입 'd', now (), user, old.*; 옛날 복귀; elsif (tg_op = 'update') emp_audit에 삽입 'u', now (), 사용자, 새로운.*; 새로운 반환; elsif (tg_op = 'insert') emp_audit에 삽입 'i', now (), user, new.*; 새로운 반환; 끝 IF; 널 리턴; - 결과는 방아쇠 이후에 무시됩니다. 끝; $ emp_audit $ 언어 plpgsql; 와이즈 토토 emp_audit을 만듭니다 EMP에 삽입 또는 업데이트 또는 삭제 후 각 행에 대해 프로 시저 Execute process_emp_audit ();
이전 예제의 변형은 감사 테이블의 메인 테이블, 각 항목이 마지막에있을 때를 보여주기 위해 수정. 이 접근법은 여전히 전체 감사 트레일을 기록합니다 표로 변경되었지만 마지막 수정 된 타임 스탬프가 파생 된 감사 트레일 각 항목에 대한 감사 트레일에서.예제 39-5뷰에서 감사 와이즈 토토의 예를 보여줍니다pl/pgsql.
예 39-5. 에이pl/pgsql와이즈 토토 절차보기 감사
이 예제는보기에서 와이즈 토토를 사용하여 그것을 만들었습니다. 업데이트 가능하고 모든 인서트, 업데이트 또는 삭제 보기에있는 행은에 기록됩니다 (즉, 감사)emp_audit테이블. 현재 시간과 사용자 이름 수행 된 작업 유형과 함께 기록됩니다. 그리고보기는 각 행의 마지막 수정 시간을 표시합니다.
테이블 emp 생성 ( empname 텍스트 기본 키, 급여 정수 ); 테이블 작성 emp_audit ( char (1) null이 아닌 작전, userID 텍스트는 null이 아닙니다. embname 텍스트가 null, 급여 정수, 스탬프 타임 스탬프가 널 있지 않습니다 ); View emp_view as를 만듭니다 e.empname 선택, E.Salary, last_updated로 max (ea.stamp) emp e eam.empname = e.empname에서 emp_audit ea에 가입합니다 1, 2에 의해 그룹; 기능을 만들거나 바꾸십시오. update_emp_view () 와이즈 토토를 $$로 반환합니다 시작하다 - - EMP에서 필요한 작업을 수행하고 EMP_AUDIT에서 행을 만듭니다. - EMP에 대한 변화를 반영합니다. - if (tg_op = 'delete') 그러면 empname = old.empname; 찾을 수없는 경우 NULL을 반환하십시오. 끝 IF; old.last_updated = now (); emp_audit 값 ( 'd', user, old.*)에 삽입; 옛날 복귀; elsif (tg_op = 'update') EMP 업데이트 SET SALARY = NEW.SALARY WHER EMPNAME = OLD.EMPNAME; 찾을 수없는 경우 NULL을 반환하십시오. 끝 IF; new.last_updated = now (); emp_audit 값에 삽입 ( 'u', user, new.*); 새로운 반환; elsif (tg_op = 'insert') EMP 값에 삽입 (New.empname, New.salary); new.last_updated = now (); emp_audit 값 ( 'i', user, new.*)에 삽입; 새로운 반환; 끝 IF; 끝; $$ 언어 plpgsql; 와이즈 토토 emp_audit을 만듭니다 emp_view에 삽입하거나 업데이트하거나 삭제하는 대신 각 행에 대해 Execute Procedure update_emp_view ();
와이즈 토토의 사용은 다른 사람의 요약 테이블을 유지하는 것입니다. 테이블. 결과 요약은 원본 대신에 사용할 수 있습니다. 특정 쿼리 용 테이블 - 종종 실행 시간이 크게 줄어 듭니다. 이 기술은 일반적으로 데이터웨어 하우징에 사용됩니다. 측정 또는 관찰 된 데이터 테이블 (사실 테이블이라고 함) 매우 큰.예제 39-6와이즈 토토 프로 시저의 예를 보여줍니다pl/pgsql요약 테이블을 유지합니다 데이터웨어 하우스의 사실 테이블.
예 39-6. 에이PL/PGSQL유지 관리 절차 요약 테이블
여기에 자세히 설명 된 스키마는 부분적으로입니다.식료품 점예제데이터웨어 하우스 툴킷Ralph Kimball의
- - 메인 테이블 - 시간 차원 및 판매 사실. - 테이블 생성 time_dimension ( time_key 정수가 null, day_of_week 정수 NOT NULL, day_of_month Integer Not Null, 월 정수가 널이 아닌 쿼터 정수는 null이 아닙니다. 연도 정수는 null이 아닙니다 ); time_dimension (time_key)에서 고유 한 색인 time_dimension_key를 만듭니다. 테이블 생성 sales_fact ( time_key 정수가 null, Product_key Integer Not Null, store_key 정수 NOT NULL, 득 Unit_Sold Integer Not Null, 숫자 숫자 숫자 (12,2)는 널 not ); sales_fact (time_key)에서 색인 sales_fact_time을 만듭니다. - - 요약 테이블 - 시간별 판매. - 테이블 생성 sales_summary_bytime ( time_key 정수가 null, 득 Unit_SOLD 숫자 (12) NOT NULL, aMond_cost 숫자 (15,2)는 null이 아닙니다 ); sales_summary_bytime (time_key)에서 고유 한 인덱스 sales_summary_bytime_key 만들기; - - 기능 및 와이즈 토토는 업데이트, 삽입, 삭제시 요약 된 열을 수정합니다. - 기능을 만들거나 교체합니다 $ maint_sales_summary_bytime $입니다 선언하다 delta_time_key 정수; delta_amount_sold 숫자 (15,2); delta_units_sold 숫자 (12); delta_amount_cost 숫자 (15,2); 시작하다 - 증분/감소량을 계산하십시오. if (tg_op = 'delete') 그러면 delta_time_key = old.time_key; delta_amount_sold = -1 * old.amount_sold; delta_units_sold = -1 * old.units_sold; delta_amount_cost = -1 * old.amount_cost; elsif (tg_op = 'update') - time_key를 변경하는 업데이트 금지 - - (Delete + Insert가 가장 많이 - 변경이 이루어집니다). if (old.time_key! = new.time_key) 그러면 'Time_key의 업데이트 : % - % 허용되지 않음', 예외 제기, old.time_key, new.time_key; 끝 IF; delta_time_key = old.time_key; delta_amount_sold = new.amount_sold -Old.amount_sold; delta_units_sold = new.units_sold -Old.units_sold; delta_amount_cost = new.amount_cost -Old.amount_cost; elsif (tg_op = 'insert') delta_time_key = new.time_key; delta_amount_sold = new.amount_sold; delta_units_sold = new.units_sold; delta_amount_cost = new.amount_cost; 끝 IF; - 새 값으로 요약 행을 삽입하거나 업데이트하십시오. << insert_update 고리 SALLE_SUMMARY_BYTIME 업데이트 set aveS_SOLD = aMber_sold + delta_amount_sold, units_sold = units_sold + delta_units_sold, aMber_cost = aMber_cost + delta_amount_cost 여기서 time_key = delta_time_key; 발견되면 insert_update를 종료합니다. 시작하다 sales_summary_bytime에 삽입 ( time_key, aMber_sold, Unit_Sold, aMber_cost) 값 ( delta_time_key, delta_amount_sold, delta_units_sold, delta_amount_cost ); insert_update 종료; 예외 그럼에도 불구하고 - 아무것도하지 않습니다 끝; 엔드 루프 insert_update; 널 리턴; 끝; $ maint_sales_summary_bytime $ 언어 plpgsql; 와이즈 토토 maint_sales_summary_bytime을 만듭니다 sales_fact에서 삽입 또는 업데이트 또는 삭제 후 각 행에 대해 실행 절차 maint_sales_summary_bytime (); sales_fact 값 (1,1,1,10,3,15)에 삽입; Sales_Fact 값 (1,2,1,20,5,35)에 삽입; sales_fact 값에 삽입 (2,2,1,40,15,135); Sales_Fact 값 (2,3,1,10,1,13)에 삽입; sales_summary_bytime에서 *를 선택하십시오. sales_fact에서 삭제하는 곳에서 product_key = 1; sales_summary_bytime에서 *를 선택하십시오. Sales_fack Set units_sold = units_sold * 2 업데이트; sales _summary_bytime에서 * 선택 *