이준빈은 호박머리

IT 프로그래밍 개발 정보 블로그, 이준빈은 호박머리 입니다.

Database/ORACLE

오라클 forms develope 개발 시 간단한 코드 모음

준콩이 2012. 8. 14. 13:18
반응형

개발 참조 자료

 

ERD 에서 1:N 관계의 OUTER-JOIN(적은 쪽에 표시)시 N쪽에 (+)표시를 붙여 준다.

테이블에 상관없이 어떤 쪽이 다 보여줘야하느냐에 따라 (+)를 붙임.

l         &NEW 는 단축키 기능

l         WHEN VALIDATE Triger : 쿼리 도중에 변화가 발생시 그 변화를 추가하거나 변경 및 삭제 하기위해 WHEN_VALIDATE_ITEM 트리거를 씀.

n          EMP블록의 Query 도중에 부서이름이 변경될 수 있으므로 When-Validate-Item 트리거에 같은 코드를 추가한다.

n          데이터베이스 블록의 QUANTITY를 임의의 보이지 않는 텍스트 아이템을 하나 만들어 데이터베이스 블록의 QUANTITY 값을 복사해 놓는다. 그리고 해당 데이터베이스 블록의 컬럼하나가 변경 되면 역시 복사된 아이템의 같은 ROW가 지정된다. 그래서 변경되기 전의 복제된 숨어있는 컬럼의 값을 QTY_SUM에서 빼고 변경된 값을 더하면 된다.

u                 :CI_LINE_COST.QTY_SUM := (:CI_LINE_COST.QTY_SUM - NVL(:CI_LINE.QUANTITY1,0)) + NVL(:CI_LINE.QUANTITY,0);

예제) IF :CI_LINE.QUANTITY IS NOT NULL THEN

                                   :CI_LINE_COST.QTY_SUM := (:CI_LINE_COST.QTY_SUM - NVL(:CI_LINE.QUANTITY1,0)) + NVL(:CI_LINE.QUANTITY,0);

                  END IF;

l         WINDOW 타이틀 변경 : WHEN_NEW_FOR_INSTANCE를 사용.

set_item_property( 'EMP.DEPT', LOV_NAME, 'LV_Q_ITEM' );

l         ITEM 속성 변경

APP_ITEM_PROPERTY.SET_PROPERTY ( 'FIND_CONTROL.L_CMS_CODE'  ,  ENABLED,         PROPERTY_FALSE ) ; -- 아이템이 보이지 않음.

 

 아이템을 enable/disable 하는 방법

set_item_property('initial_show_blk.bt_change', enabled, property_true);

SET_ITEM_PROPERTY('CI_LINE_CTRL.DESCRIPTION_ITEM_INSERT',ENABLED, PROPERTY_FASLE);

ex) if :system.current_form = 'SOP_FAC_CHOOSE' then
        set_item_property('blk_menu.BT_DB_SUB_MANG', enabled, property_false);
end if;

 

l         CLEAR_BLOCK(NO_VALIDATE); => LINE BLOCK의 내용을 먼저 CLEAR시킨 뒤 다시 내용을 띄운다.

n          APP_FIND.CLEAR; -- TRIGER가 일어난 BLOCK을 지워준다.

l         Show_view(‘view_name’);

l         hide_view(‘view_name’);

l         SUM(LINES.RENTAL_FEE_AMOUNT + NVL(LINES.RETURN_DELAY_FEE_AMOUNT,0))

=> SUM 연산에도 + 사용이 가능

l         DECODE(SIGN(ROUND(MONTHS_BETWEEN(SYSDATE,COPI.PURCHASED_DATE),0) - 4),'OLD','NEW') T_PURCH

ð       SIGN함수는 -1과 0과 1을 반환 한다.

l         DECODE(SIGN(MONTHS_BETWEEN(SYSDATE, COPI.PURCHASED_DATE+4)), 1,'OLD','NEW') T_PURCH (강추)

l         to_number(DECODE(C1,'null',0,C1)) : decode후 number형태로 데이터형 변경

위의 DECODE가 그룹 함수와 같이 사용되어 GROUP BY에 사용 시 COPI.PURCHASED_DATE를 ORDER BY에 써야한다. group by가 order by절을 대신할 수 있다.(굳이 2개를 같이 쓸 필요가 없다.)

l         Group by 절은 그룹함수를 사용하고 그 묶음 단위로 데이터를 배열한다. 그런데 만약 group by a,b,c,d,e 라면 a라는 묶음에 그 안에 b라는 묶음을 두고 다시 그 안에 c라는 묶음을 두고 다시 그 안에 d라는 묶음을 두고 다시 그안에 e라는 묶음으로 사용된다.

l         서로 다른 캔버스를 사용할 때 윈도우도 다른 것을 사용해라.

l         LOV를 이용할 때 숨어있는 아이템을 이용해서 데이터를 가져와라.

l         데이터 블록의 텍스트 아이템은 테이블의 컬럼과 유사한 역할을 한다.

l         SET_ITEM_PROPERTY('B_RENTAL_LINES.RENTAL_PAPER', VISIBLE, PROPERTY_FALSE);

ð       ITEM 자체가 보이지 않는다.

 

날짜변환

l         TO_CHAR (sysdate, 'YYYY/MM/DD HH24:MI:SS')

l         날짜 변환 시      TO_DATE(‘2006-08-01’,’YYYY-MM-DD’)

l         작업한 시간에 대해  시, 분, 초로 나눔.

to_char(trunc((working_time)/3600))||' Hours '
       ||to_char(trunc(mod((working_time),
3600)/60))||' Minutes '
       ||to_char(trunc(mod(mod((working_time),
3600),60)))||' Seconds'

l         해당월의 1일짜 : SELECT TRUNC(SYSDATE,'MM')

l         select *
from iinvk_order_transfer_if a
where a.transfer_date = to_date(
'20061101 08','yyyymmdd hh24');

l         날짜 조정(시간이 세밀하게 조정됨) => 날짜 ? 0.08   ,교환환불현황조회???? = >

SELECT schedule_ship_date-0.07
from   oe_order_lines_all;

l         SYSDATE > TO_DATE(LINES.EXPECTED_RETURN_DATE,'DD-MON-YYYY')

n          SYSDATE와 날짜를 비교할 때 TO_DATE(날짜,’DD-MON-YYYY’)를 반드시 해야한다.

n          TO_char(SYSDATE,'yyyy-mm-dd') : sysdate를 yyyy-mm-dd로 출력

l         날짜 끼리 크기 비교

WHERE TO_CHAR(XIOA.REQUEST_DATE,'YYYYMMDD') >= TO_CHAR(:CONTROL.DATE_FROM,'YYYYMMDD') AND  TO_CHAR(XIOA.REQUEST_DATE,'YYYYMMDD') <=  TO_CHAR(:CONTROL.DATE_TO,'YYYYMMDD') ;

날짜 형태를 TO_CHAR형태로 통제한다.

l         SELECT *
FROM  pm_post_conv_inf 

WHERE addr_seq IS NULL 
AND   create_date >= to_date(
'20061024','yyyymmdd');

=> 10월 24일 날짜를 비교할 때 그 일짜보다 큰(>)를 넣어서 비교해야 정확한 데이터가 나옴.

l         DELETE_LIST_ELEMENT(‘블록명.LIST_ITEM명’,3) : 리스트의 3번째를 삭제하라.

l         if :system.current_form = 'SOP_FAC_CHOOSE' then
    set_item_property('blk_menu.BT_DB_SUB_MANG', enabled, property_false);
  end if; 현재 블록에선 이 명령이 안먹음. 그래서 다른 블록 및 아이템으로 이동 후 명령어를 처리해야함.

ð       현재의 폼이 맞다면 아이템 속성을 비활성화 시켜라.

l         SET_ITEM_PROPERTY('bem_ci_headers_ship.BL_NO',CURRENT_RECORD, PROPERTY_FALSE);=> 현재아이템이 존재하는 레코드 한줄을 비활성화시킴.

l         SET_RECORD_PROPERTY(CURRENT_RECORD, ‘블록명’, ENABLED, PROPERTY_FALSE) ???

l         SET_ITEM_PROPERTY(‘아이템명’, VISIBLE, PROPERTY_FALSE);

l         TO_CHAR(SYSDATE,'YYYY-MM-DD');

l         CLEAR_MESSAGE;

☆ Select한 Column의 값을 넘겨 줄 INTO절이 반드시 포함되어야 한다.

☆ Query로부터 반드시 하나의 row가 리턴되어 넘어와야 한다(에러 발생).

l         만약 여러 개의 row를  핸들링해야 하는 경우라면 커서를 사용해야 한다.

l         SELECT구문에서 다중 열을 반환해서 INTO로 넣어줄 때 문제가 발생.

n          INTO는 단 하나의 값만을 반환 받는다. 따라서 다중 열은 INTO가 수용할 수 없기 때문에 COUNT(*)와 WHERE조건 문에서 적당것 조건을 주어 COUNT(*)로 이용한다.

l         DELETE_LIST_ELEMENT('B_CONTROL.리스트명',2);

l         아이템 속성값에서 requred를 yes로 셋팅하면 erp application상에서 입력하지 않은 필드가 노란색으로 표기

l         SET_ITEM_INSTANCE_PROPERTY : set_item_property문장을 아래처럼 바꾸면 해당레코드에 대해서만 처리가 됩니다.

n          Set_Item_Instance_Property( 'XOMK_ORDER_LOSS_V.LOSS_QTY'  , CURRENT_RECORD, UPDATE_ALLOWED , PROPERTY_TRUE);

Set_Item_Instance_Property( 'XOMK_ORDER_LOSS_V.LOSS_QTY'  , CURRENT_RECORD, UPDATE_ALLOWED , PROPERTY_FALSE);

n          SET_ITEM_INSTANCE_PROPERTY(‘B_RENTAL_LINES.체크아이템’,CURRENT_RECORD,INSERT_ALLOWED, PROPERTY_FALSE) : 체크 아이템에 한번 체크되면 두번 다시 체크를 풀수 없다. 한 아이템의 그 놈만 유일하게 속성을 제어할 수 있다.

 

n          체크된 아이템이 출력된 후 노란색으로 변경

IF :CI_LINE.PRINTED_FLAG = 'Y' THEN

          SET_ITEM_INSTANCE_PROPERTY('CI_LINE.CHK',CURRENT_RECORD, VISUAL_ATTRIBUTE, CHECK_COLOR_CHANGE');

        END IF;

VISUAL ATTRIBUTE 네비게이션 창에서 속성을 하나 생성한 후 위의 코딩을 한다.

n          출력된 상태를 표기하기 위해 체크 박스를 노란색으로 변경 시킴 => SET_ITEM_INSTANCE_PROPERTY('CI_LINE.CHK',CURRENT_RECORD, VISUAL_ATTRIBUTE, 'CHECK_COLOR_CHANGE'); 네비게이터에서 VISUAL ATTRIBUTE의 속성 창에 백그라운드 컬러를 ‘YELLOW’로 변경하고 ‘이름’을 CHECK_COLOR_CHANGE로 주면 SET_ITEM_INSTANCE_PROPERTY에 적용이 가능하다.

 

l         TO_CHAR(SYSDATE) : DD_MOD_YYYY

l          미세조정 : shift + 방향키

l          메뉴 -> View -> stack viewed 로 스택캔버스 두개를 메인캔버스에 로드시킴. 만약 stack viewed를 선택했을 시 main canvas에 올라 오지 않으면 스택캔버스의 속성에서 physical 부분의 windows부분을 main으로 변경해라. 

l          스택캔버스 추가 : 캔버스에 추가 버튼을 누른 후 속성창에서 스택으로 변경.

메인캔버스에서 필요한 아이템을 선택한 후 속성창에서 캔버스 선택을 보내고자하는 스택캔버스를 선택하면 아이템이 일괄 이동됨.

l          체크박스의 속성창에서 checked : Y, unchecked : N으로 선택 (속성 창에서 database 속성은 no로 반드시 설정)

l          레코드 마다 커서의 위치를 표시하는 방법 : 아이템을 하나 추가한 후 속성창 -> sub information -> current_record_indicator를 선택한다.

l          캘린더의 로딩 : SUBCLASS_INFORMATION에서 TEXT_ITEM_REQ_DATE를 선택하면 캘린더의 속성을 사용할 수 있다. 이것의 속성은 DD-MON-YYYY형태로 출력한다는 것이다.

l          WHEN_NEW_FORM_INSTANCE

lgis_form.event ( 'WHEN-NEW-FORM-INSTANCE' ) ;

 

:CTRL.RETURN_DATE_S := SYSDATE;

:CTRL.RETURN_DATE_E := SYSDATE;

 

SHOW_VIEW('S_STANDARD');

SHOW_VIEW('S_DESCRIPTION');

l         만약 실행했을 때 전체 데이터블록이 보이지 않을 때는 실행의 흐름을 생각해라. 그래서 순차적으로 CTRL -> CALENDAR -> PROGRESS INDICATOR -> EPO_RETURN_V

그리고 캔버스도 제일 상위의 MAIN -> S_STANDARD -> S_DESCRIPTION 으로 흐름을 생각해서 배열 해라.

l         아이템(text item) 중에 데이터베이스 속성이 없는데 속성 값을 yes로 체킹하면 절단 난다. 반드시 no로 해야한다. 잘 챙겨라. 데이터베이스와 상관없는 버튼이나 DISPLAY같은 항목을 모아두기 위해 CONTROL

l         파일명을 잘보고 올려라.제발 좀.~~~~ (대처방안 : 작업파일을 하나 정하고 백업본으로 _1,_2 이와 같이 파일명을 증가시키면서 보관한다.)

l         WHERE 조건절을 만들기 위해 연달아 붙이는 방법

V_WHERE := 'TRANSACTION_DATE >= :CTRL.RETURN_DATE_S AND TRANSACTION_DATE  <= :CTRL.RETURN_DATE_E AND PARENT_TRANSACTION_TYPE = DECODE(:CTRL.SEARCH_CONDITION,4, PARENT_TRANSACTION_TYPE, :CTRL.SEARCH_CONDITION)'; 디코드시 1:1관계를 설정하면 전체 조회를 의미한다. Search_condition은 리스트 박스를 의미 하고 4는 4번째 속성을 의미한다. 즉 4번째 속성은 전체 조회를 하겠다는 의미이다. 이것은 조회하고자 하는 테이블엔 값이 없다. 따라서 디코드를 사용하여 전체 조회를 할 수 있도록 코딩하고 그리고 그게 아니라면 리스트 아이템의 1,2,3 정도를 선택한다는 의미이다.

l          무조건 뒤쪽에 ‘AND 조건문’을 넣기위해서 변수 초기화 부분에 V_WHERE VARCHAR2(20000) ‘1=1’;로 둔다.

     IF :CTRL.ITEM IS NOT NULL THEN

         V_WHERE := V_WHERE || ' AND ITEM_CODE = :CTRL.ITEM'; --아이템 코드 (반드시 작은 따옴표 다음엔 한칸 띄어야한다.

     END IF;

   

     IF :CTRL.DESCRIPTION IS NOT NULL THEN

           V_WHERE := V_WHERE || ' AND DESCRIPTION = :CTRL.DESCRIPTION';  --아이템 명

     END IF;

 

IF :CTRL.SUPPLIER_NAME IS NOT NULL THEN

           V_WHERE := V_WHERE || ' AND VENDOR_NAME = :CTRL.SUPPLIER_NAME';  -- 공급자 명

     END IF;

   

     IF :CTRL.SITE_NAME IS NOT NULL THEN

           V_WHERE := V_WHERE || ' AND VENDOR_SITE_CODE = :CTRL.SITE_NAME';  -- site명

     END IF;

   

     IF :CTRL.SUB_INVENTORY IS NOT NULL THEN

           V_WHERE := V_WHERE || ' AND SUBINVENTORY = :CTRL.SUB_INVENTORY';  -- sub_inventory

     END IF;

   

l          set_block_property

1. SET_BLOCK_PROPERTY('EPO_RETURN_V',DEFAULT_WHERE,V_WHERE); -- 블록의 속성을 지정하는 명령어(SET_BLOCK_PROPERTY), 데이터 블록이나 테이블, 뷰의 디폴트 where조건절을 구성. 즉 SELECT * FROM EPO_RETURN_V WHERE ~~~~라는 의미.

SET_BLOCK_PROPERTY(‘EMP’,ORDER_BY, VORDER); => EMP 테이블을 정렬하는데 VORDER이라는 컬럼을 기준으로 정렬 함.

2. set_block_property(:system.cursor_block,DEFAULT_WHERE,is_where);

3. 상위의 메뉴에 삽입 아이콘을 비활성화 시킴 : SET_BLOCK_PROPERTY('CI_LINE', INSERT_ALLOWED, PROPERTY_FALSE);

4. 스크롤바의 위치 지정 :  Set_Block_Property('XOMK_RDC_V', BLOCKSCROLLBAR_POSITION, 8.791, 1.722);

5. SET_BLOCK_PROPERTY('SHIPPING_HOLD', default_where, v_default_where); -- 'SHIPPING_HOLD'는 테이블명(데이터블록명) 즉 form절을 구성하는 테이블이나 데이터 블록을 의미

l          v_default_where 의 지정

v_default_where := ' line_id in ( select a.line_id from xomk_req_number_v a where a.req_number = :SHIPPING_HOLD_CONTROL.DL_NUMBER ) '||

                                     ' and   ulis_send_flag <> ''C'' '||

                                     ' and   line_status_code = ''AWAITING_SHIPPING'' '||

                                     ' and   cust_account_id  = :FIND_CONTROL.L_CUSTOMER ';

 

l          lock name에 관한 lock handle을 구함. 다중사용자가 같은 row상에 동시에 update하는 것을 방지

DBMS_LOCK.ALLOCATE_UNIQUE (gv_lockname, gv_lockhandle) ;

l          시간Term을 두어 첫번째를 제외한 시도는 lock request시 Error를 유발시킴

DBMS_LOCK.SLEEP (0.1) ;

l          락모드에서 request의 값이 없다면 ‘0(성공)’을 반환.

DBMS_LOCK.REQUEST (gv_lockhandle, DBMS_LOCK.SSX_MODE, 0.1) ;

The following table summarizes the return values of the function.

Return Value

Description

0

Success

1

Timed out

2

Deadlock

3

Parameter error

4

Do not own lock; cannot convert

5

Illegal lockhandle

l          모든 처리가 성공적으로 끝난 후 LOCK를 해제 함.

lv_ret := DBMS_LOCK.RELEASE (gv_lockhandle) ;

l          APP_FIND.FIND('EPO_RETURN_V'); -- 쿼리를 실행(오라클 에플리케이션에서 EXECUTE_QUERY와 같은 기능)

ð       GO_BLOCK(‘B_EMP’); ‘ ’안에는 갈 블록의 이름을

    EXECUTE_QUERY ; 그 블록에서 쿼리를 실행하라.

l         set_block_property(:system.cursor_block,DEFAULT_WHERE,is_where);

l         SELECT DISTINCT DECODE(PARENT_TRANSACTION_TYPE,1,'입고반품'

                                                              ,2,'검사반품'

                                                              ,3,'납품반품', NULL)

ð       DECODE시 다중 조건을 사용하는 예

 

l         컨트롤 블록 속성에서 database no라고 표기하면 모든 아이템에 database 가 no로 셋팅

l         APP_FIND.FIND('EPO_RETURN_V');

l         FND_MESSAGE.DEBUG('반품일자의 시작일이 입력되지 않았습니다.');

       RAISE FORM_TRIGGER_FAILURE; -- Processing 처리가 잘못 됐을 경우 더 이상 진행을 하지않고 빠져 나옴.

ð       오라클 APPLICATION에서 메시지를 띄울 때 사용.

l          PRE_QUERY, POST_QUERY는 MOUDLE과 BLOCK단위의 트리거에서 찾을 수 있다.

l          Post-Query Trigger는 매 row를 Query해 가져올 때마다 수행되며, Block Level 이상에서 선언해 주어야 한다. 즉, 한번의 Query로 10개의 레코드를 가져온다고 가정할 때, Pre-Query Trigger는 Query수행 전
  1번 수행되지만,   Post-Query Trigger는 각각 row가 Fetch될 때마다 수행되어 총 10번이 수행된다.

l          설정을 다 하고도 프로그램의 데이터가 나오지 않는다면 아이템의 속성에서 DATABASE 속성의 DATA ITEM이 정확한지 점검해라.

l          현재 커서가 있는 레코드의 한줄을 파란색으로 표시하는 방법 : current record visual attribute group => SELECTED_DATA

l          LOOP 사용방법 및 체크박스 ALL로 됐을 때 블록레코드 부분에 전체 체크박스를 체킹하는 방법

GO_BLOCK('B_AP_INVOICES_ALL');  

    FIRST_RECORD;

    LOOP

              :B_AP_INVOICES_ALL.N_CHECK := :B_CON_CHECK.N_CHECK_ALL;

                EXIT WHEN :SYSTEM.LAST_RECORD = 'TRUE';

                NEXT_RECORD;

      END LOOP;

l          위자드로 만든 데이터블록의 필드에 추가로 필드를 넣고 난 뒤 어떤 값을 계산하여 넣거나 다른 쿼리 문을 삽입할 때 post trigger를 사용한다.

l          예외 처리

1. EXCEPTION

    WHEN NO_DATA_FOUND THEN

              FND_MESSAGE.DEBUG('데이터가 없습니다.');

WHEN TOO_MANY_ROWS THEN

FND_MESSAGE.SET_NAME('FND','중분류에 해당 대분류 코드가 한개 이상입니다.');

              FND_MESSAGE.ERROR;

              RAISE FORM_TRIGGER_FAILURE;             

  WHEN OTHERS THEN

        FND_MESSAGE.DEBUG('이상현상 발생.'||SQLCODE|| ' - ' ||SQLERRM);

2. EXCEPTION

When no_data_found then

      message('insert가 안됨');

WHEN OTHERS then

     message(' '||SQLCODE||' '|| SQLERRM); 

END;

l          FOR 루프

FOR  CUR_LI IN LINE_CUR LOOP             

       :B_RENTAL_LINES.TITLE := CUR_LI.T_NAME;

             :B_RENTAL_LINES.COPY_NO := CUR_LI.T_COPY;

    DELETE_LIST_ELEMENT('B_RENTAL_LINES.STATUS',3);  -- 리스트 아이템 하나를 삭제 하는 방법

       IF UPPER(CUR_LI.T_STATUS) = 'CLOSE' THEN

                  SET_ITEM_PROPERTY('B_RENTAL_LINES.STATUS', ENABLED, PROPERTY_FALSE);

        ELSE

                   SET_ITEM_PROPERTY('B_RENTAL_LINES.STATUS', ENABLED, PROPERTY_TRUE);

        END IF;       

       NEXT_RECORD; -- 굳이 쓰지 않아도 될 듯….

 END LOOP;

l          프로시저 생성방법 (PROGRAM UNITS에 추가 버튼을 클릭하여 프로시저 생성가능

PROCEDURE date_check(RETURN_DATE_S  DATE

                    ,RETURN_DATE_E  DATE)

IS

 

BEGIN

IF RETURN_DATE_S IS NULL THEN

       FND_MESSAGE.DEBUG('반품일자의 시작일이 입력되지 않았습니다.');

       RAISE FORM_TRIGGER_FAILURE;

    ELSIF RETURN_DATE_E IS NULL THEN

              FND_MESSAGE.DEBUG('반품일자의 종료일이 입력되지 않았습니다.');

       RAISE FORM_TRIGGER_FAILURE;

    ELSIF RETURN_DATE_S > RETURN_DATE_E THEN

              FND_MESSAGE.DEBUG('반품일자의 시작일이 종료일보다 큽니다.');

       RAISE FORM_TRIGGER_FAILURE;

END IF;

 

END;

l          FOR LOOP

 

procedure edu16_01 IS

begin

     FOR loc_num  IN (SELECT deptno

                      FROM dept

                      WHERE  loc = 'CHICACO') LOOP

          UPDATE emp

          SET comm = nvl(comm,0) + 100    

          WHERE deptno = loc_num.deptno;            

     END LOOP;

COMMIT;

end edu16_01;

 

l          프로시저의 파라미터

PROCEDURE insert_rcv_txn_proc

          (p_organization_id IN hub_rcv_transactions.organization_id%TYPE, --조직 아이뒤

           p_organization_code IN hub_rcv_transactions.organization_code%TYPE,--조직 코드

           p_vendor_site_id IN hub_rcv_transactions.vendor_site_id%TYPE, --사업자 코드 id

           p_vendor_site_code IN hub_rcv_transactions.vendor_site_code%TYPE,--사용자 번호

           p_inventroy_item_id IN hub_rcv_transactions.inventory_item_id%TYPE, --품목 아이뒤

           p_item_number IN hub_rcv_transactions.item_number%TYPE, --품목번호

           p_rcv_quantity IN hub_rcv_transactions.rcv_quantity%TYPE,--입고수량

           p_rcv_date IN hub_rcv_transactions.rcv_date%TYPE,--입고일자

           p_shipment_num IN hub_rcv_transactions.shipment_num%TYPE,--항번

           p_po_header_id IN hub_rcv_transactions.po_header_id%TYPE,--주문 header 아이뒤

           p_po_release_id IN hub_rcv_transactions.po_release_id%TYPE,--주문 release 아이뒤

           p_po_line_id IN hub_rcv_transactions.po_line_id%TYPE,--주문 line 아이뒤

           p_hub_receipt_num IN hub_rcv_transactions.hub_receipt_num%TYPE,--hub 납품표번호

           p_hub_receipt_seq_num IN hub_rcv_transactions.hub_receipt_seq_num%TYPE) IS--납품표번호 seq

 

WHEN OTHERS THEN
          RAISE FND_API.G_EXC_UNEXPECTED_ERROR;

 

l          ERP 개념 및 용어정리

PO : 구매 => RFQ(견적요청서), BPA(장기계약, 단가, 업체 결정)

PR : 구매요구

WIP (work in process) : 생산공정 => RECEIVING -> (Receipt(납품), Accept(검사) -> WIP공정 투입 <- Receiving(입고)

INVENTORY (자재창고)

OSP (OUT-Sorching plan) : 생산 과정 중 어떤 한 부분을 업체에 아웃소싱하여 그 공정을 담당하게 하는 것

RDC (Regional  Distribution Center : 지역적 분배 센터)

 

업체 -> Receipt -> Accept -> receiving

반품       <-                                    Return to vendor

                                <-

                                            <- 

 

l         update    edu_media_title_copies_16

set rented_flag = decode(:B_RENTAL_LINES.STATUS, 'Open' , 'Y' ,'N')

,address2 = '270 번지'

where          copy_id = :B_RENTAL_LINES.COPY_NO;

l         윈도우 창 숨기기 : HIDE_WINDOW('PRINTER_SETTING');

l         Forms_path : 한글이 들어가면 되지 않는 현상. : C:\orant\TOOLS\OPEN60\PLSQLLIB;C:\form_path;C:\Oracle Library\app_pll;C:\Oracle Library\Resource;C:\Oracle Library\Source;C:\Oracle Library\standard_form;

l         fnd관련 선언이 안됐다는 오류가 뜨면 로그인하지 않은 의미. 그래서 로그온하면 해결됨.

l         Boolean 타입 : 작은 따옴표없이 그냥 false, true를 쓰면 된다.

v_printer_set = false

l         프린트 속성 체크 및 출력물 인쇄

PROCEDURE EXEC_PRINT(P_NAME    IN VARCHAR2

                    ,P_PRINTER IN VARCHAR2

                    ,P_CNT     IN NUMBER)    

IS

 

  V_TRX_ID VARCHAR2(10); -- 리포트에 보낼 파라미터

  V_REQ_ID NUMBER;  -- REQUEST NUMBER

  V_CNT NUMBER := 0; -- 프린트한 리포트수

  V_DUMMY BOOLEAN;

  v_printer_set BOOLEAN; -- 프린트 세팅 유무

 

BEGIN

         GO_BLOCK('EPO_RETURN_V');

         FIRST_RECORD;    

 

         LOOP

               v_printer_set := fnd_request.set_print_options(p_printer,'LANDWIDE', p_cnt, NULL, NULL);   -- 리포트 출력을 위한 프린트 세팅 

 

 -------------------------- 프린트 세팅이 실패하면 메세지를 표시 --------------------

               IF v_printer_set = false THEN 

                        FND_MESSAGE.DEBUG('프린트세팅이 잘못되었습니다.');

                        RAISE FORM_TRIGGER_FAILURE;

        END IF;

 

        IF :epo_return_v.LINE_CHKBOX = 'Y' THEN     -- 체크 박스에 체크유무 파악

                               v_trx_id:= to_char(:epo_return_v.transaction_id);

                 -- EPOR0005_1 출력물명

                 v_req_id := fnd_request.submit_request('WINWIN','EPOR0005_1',null,null,FALSE,

                                                    to_char(:parameter.org_id),v_trx_id, chr(0),'','','','','','','',

                                                                 '','','','','','','','','','','','','','','','','','','','', '','','','','','','','','','',

                                                                  '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','',

                                                                  '','','','','','','','','','','','','','','','','','','','','','','','','','','','','','');

                                -- Concurrent program에 request 요청

         if v_req_id = 0 then

                                             fnd_message.retrieve;

                                             fnd_message.error;

                              else

                                         FND_MESSAGE.DEBUG(V_CNT);

                              end if; 

        END IF;

     

     

              EXIT WHEN :SYSTEM.LAST_RECORD = 'TRUE';

        

         END LOOP;

             COMMIT;

            

           --  FND_MESSAGE.SET_NAME(FND,'MSG');

           --  FND_MESSAGE.SET_TOKEN(P_PRINTER);

      FND_MESSAGE.SHOW; -- 리포트 출력 건수 표시

      RAISE FORM_TRIGGER_FAILURE;

END;

l         스택캔버스를 메인 윈도우에 띄움(2개의 스택캔버스)

SHOW_VIEW('S_STANDARD');        --고정된 스택캔버스를 메인 윈도우상에 로딩

SHOW_VIEW('S_DESCRIPTION');

l         FND_MESSAGE.SET_NAME('WINWIN','프린트세팅이 잘못되었습니다.');

         FND_MESSAGE.SHOW;

l         Item을 입력 후 탭키를 누르면 바로 옆의 아이템 명에 표기되도록 하는 법

n          아이템 속성 창 LOV의 validate from list를 yes로 하고 LOV에는 DISTINCT로 서로 유일하게 매칭되어야 탭키로 바로 아이템명이 기입된다.

l         LOV 속성 창에서 AUTOMATIC DISPLAY를 NO로 세팅해라. => 그래야 프로그램 실행시 바로 뜨지 않는다.

l         가로의 스크롤바는 만들러면  Stacked 캔버스를 만들어야 한다.

l         체크박스 만들기

1.아이템에 체크박스 생성

2.속성에서 VALUE WHEN CHECKED Y OR 1, VALUE WHEN UNCHECKED N OR 0을 한다

3.Check box Mapping of values =>  UNCHECKED를 한다(이부분은 실무에서 바꿀수 있다).

4. database item은 반드시 NO로 설정

TAB 캠버스는 별도의 스택캠버스로 만들어서 올라가야 한다...

*) 탭페이지가 2개이고 모든 페이지에 같은 내용이 나온다면 탭의 순서에서 스택캔버스로 만든 녀석을 제일 상위단으로 올려라.

 1. 탭캠버스로 2개의 캠버스를 보고자 한다면

    두개의 스택캔버스와 하나의 탭캔버스를 만들자

 2. 메인캔버스에서 보여줄 첫번째 스택캔버스와 탭캔버스를 가지고 VIEW에서 스택뷰를 한다

 2-1.메인캔버스에서 보여줄 두번째 스택캔버스와 탭캔버스를 가지고 VIEW에서 스택뷰를 한다

 3. 두개의 스택캔버스를 메인에 스택된 탭캔버스와 좌표를 맞추어야 한다

 3-1. 그래서 두개의 스택캠퍼스의 활성화 창의 뷰포인트의 좌표를 설정한다..

 4. 트리거 작업을 한다....주의점은 각각의 대상 이름들을 잘보아야 한다..

 

 4-1.트리거 : WHEN-TAB-PAGE-CHANGED

DECLARE

  CURRENT_TAB VARCHAR2(30) :=GET_CANVAS_PROPERTY('C_TAB_CONTROL',TOPMOST_TAB_PAGE);--만든 탭캠버스의 이름

 begin

  if current_tab = 'PAGE 52 ' then null; --탭캠버스의 첫번째 탭이름 ;

  go_item('B_AP_INVOICES_ALL.NO');--첫번째 스택 캠버스의 커서가 갈 레코드의 이름

set_view_property('C_EDU19', visible, property_true);--첫번째 스택 캠버스 이름..

SET_VIEW_PROPERTY('S_SHIPMENT1',VISIBLE,PROPERTY_TRUE); 탭캔버스에 올라가 있는 스택 캔버스를 보이게 한다.

  set_view_property('C_TAB_2', visible, property_false);--두번째 스택 캔버스 이름

  elsif  current_tab = 'PAGE 53 ' then null; ----탭캠버스의 두번째 탭이름

  go_item('B_EDU19_AP_INVOICE_DETAIL.INVOICE_ID');--두번째 스택 캠버스의 커서가 갈 레코드의 이름

         set_view_property('C_TAB_2', visible, property_true);--두번째 활성화

         set_view_property('C_EDU19', visible, property_false);--첫번째 비활성화        

  end if;

 end;

align : 정렬시키다.

 

4-2. 트리거 when_new_form_instance

  set_view_property('sc_emp1', visible, property_true);--첫번째 보여줄 스택 캠버스

set_view_property('sc_emp2', visible, property_false);--두번째 보여줄 스택 캠버스    

l           트리거를 사용하지 않고 program unit에서 사용 하는 방법 : copy('SAVE', 'global.folder_action');

execute_trigger('folder_action');

l          탭캔버스의 현재 탭페이지를 선언하는 부분 => CURRENT_TAB VARCHAR2(30) := GET_CANVAS_PROPERTY('TAB_BEMF',TOPMOST_TAB_PAGE);

n          탭 캔버스의 탭을 변경하기 위해 IF CURRENT_TAB = 'CI_PL_HEADER1' THEN ~~~

n          탭캔버스에 바로 데이터블록을 붙인 경우 따로 SHOW나 HIDE를 쓰지 않고 바로 코딩하면 된다.

l          application상에서 탭캔버스위에 데이터블록의 내용이 나오게 하는 방법으로 data block의 순서를 control 블록 위에 놓으면 나온다.

l          TRUNC(‘25-JUN-99’,’MONTH’) → 01-JUN-99

l          현일자의 1일날을 셋팅

-. Select TRUNC(SYSDATE,'MM')

From dual;

-. select TO_DATE(TO_CHAR(SYSDATE,'YYYYMM')||'01','YYYYMMDD')
from dual;

l          한달치 즉(10월 1일 ~ 10월 31일 오후 11:59:59)

SELECT to_date(to_char(SYSDATE,'yyyymm')||'01','yyyymmdd')
      ,trunc(sysdate) + .
99999 ? 마감 당일

FROM  oe_order_lines_all;

l         TRUNC(SYSDATE-1,'MONTH'); => 현 일자에서 한달 전의 1일자로 셋팅.

l         MAIN캔버스 -> 스택캔버스 -> 탭캔버스

l          소스 구문에 문제가 없을 시 체크박스와 라디오박스가 같은 블록에 있을 때 체크박스 ALL이 모든 개별 체크박스를 체킹하지 못하는 문제가 발생한다. 이에 라디오 박스를 다른 데이터블록에 분리해서 코딩하니 문제가 해결됐다.

l          라디오박스의 초기값 설정 : 라디오 박스 블록에 Mapping of other values에 첫번째 라디오박스의 대표값(예 : LG Logo -> G)을 설정하고, initial value에도 역시 첫번째 라디오박스의 대표값을 설정한다.

l          PRE_TEXT_ITEM : 텍스트 아이템에 자료가 입력되기 전에 트리거를 발생.

l          소수점 0.~~~표현 : 999,990.99

l         CLEAR_BLOCK(NO_VALIDATE); => 블록을 깨끗하게 청소한다.

l         해당 테이블(블록)에 데이터가 없음을 알고 싶을 때

          FND_MESSAGE.DEBUG(CUR_DIFFERENCE%ROWCOUNT);

     

      IF CUR_DIFFERENCE%ROWCOUNT = 0 THEN

         FND_MESSAGE.SET_NAME('WINWIN','PL_LINE의 수량과 CI_LINE의 수량이 동일 합니다.');                

         FND_MESSAGE.SHOW;

      END IF;

l         뷰시 ON-LOCK를 했을시 KEY MODE를 UNIQUE를 해야 함.

l         KEY COMMIT 트리거 : ????????

l         테이블로부터 값을 바로 들고 오는 블록과 합계 나 기타 테이블과 관련없는 칼럼은 다른 블록을 생성하여 데이터베이스 기능은 NO로 한후 사용하는 것이 좋다. 즉 테이블에서 불러오는 블록과 테이블과 상관없는 컬럼은 분리하는 것이 좋다.

 

트리거(trigger) 정리

ON-MESSAGE : forms내부에서 어떤 메시지가 발생했을때, 그 메시지를 나타내는 대신 트리거에 기술된 PL/SQL 문을 수행.

when이 붙은것은 뒤의 내용을 실행할때 실행되는 Trigger이며 On은 어떤행위를 대신하여 실행되는 Trigger입니다.

PRE와 POST는 어떤행위를 하기전, 하고난 후에 실행되는 Trigger.

Key는 말 그대로 해당되는 key를 눌렀을때 실행되는 Trigger

WHEN-NEW-ITEM-INSTANCE : 아이템에 새로운 값이 입력되면 그것을 감지하여 어떠한 액션을 취함.

WHEN-VALIDATE-ITEM : 아이템에 어떤 입력이 들어오면 바로 어떤 액션을 취함.

WHEN-NEW-FORM-INSTANCE 트리거

DUP는 DUPLICATE 즉 중복된 것이고 REC는 RECORD, CLR은 CLEAR, NXT는 NEXT, SCR은 SCROLL, DEL은 DELETE등이 되겠네요

Name ⇒ WHEN-NEW-FORM-INSTANCE                Scope ⇒ FORM모듈

/* 올바른 Total값을 얻기 위해, 모든 레코드의 Query를 한번에 수행한다 */ 
Execute_Query(All_Records);

l          Clear_Form; - 수정한 내용을 취소하고 Rollback을 원할 경우에 사용

l         아이템 코드 삽입시 임의의 보이지 않는 데이터컬럼을 하나 만들어 본래 아이템명을 잠시 저장하고

l         SELECT head.ROWID, head.*
FROM bem.bem_ci_headers_ship head; => update구문을 사용하지 않고 조회 후 하위 단에서 바로 변경 가능. 시스템상에서 rowid값을 자동 활당.보이진 않음.

l         SET_MENU_ITEM_PROPERTY(‘FILE.NEW’,ENABLED, PROPERTY_FALSE); 상위 메뉴의 NEW를 비활성화 시킴.

l         SUMMARY는 한 ITEM을 합계함. 포뮬라는 여러 아이템을 같이 합할 때 사용.

l         FORMS는 BASE TABLE BLOCK에 ROWID라는 HIDDEN ITEM을 가지고 있다.

n          ROWID는  CURRENT RECORD의 의미.

 

l         그 달의 처음 일 => :CONTROL.DATE_FR := TO_DATE(TO_CHAR(LAST_DAY(ADD_MONTHS(SYSDATE, -1))+1, 'YYYY-MM-DD'), 'YYYY-MM-DD');

l         조회일 쪽에 달력이 뜰수 있도록 LOV : ENABLE_LIST_LAMP를 선택 한 후 계속 팝업창이 뜨는 문제가 발생 => 아이템 속성에서 VALIDATE FROM LIST => NO로 선택한 후 문제가 해결.

l         탭의 페이지 ID를 구하는 FUNCTION : 만들어진 프로그램에서 복사하여 사용.

사용방법 => :control.tab_id := control.get_tab_id;

FUNCTION get_tab_id RETURN varchar2

IS

           tp_nm   VARCHAR2(30);

           tp_id   TAB_PAGE;

           tp_lb   VARCHAR2(30);

BEGIN

           tp_nm := GET_CANVAS_PROPERTY('C_TAB', topmost_tab_page);

           tp_id := FIND_TAB_PAGE(tp_nm);

           tp_lb := GET_TAB_PAGE_PROPERTY(tp_id, label);              

                  return tp_lb;

 

END      get_tab_id;

 

package에서 function의 선언

FUNCTION  GET_FORMAT_IDEN_FUNC  ( P_NUMBER              IN     VARCHAR2
                                  ) RETURN VARCHAR2;

 

SELECT *
fROM     xark_customer_history a

WHERE    a.creation_date BETWEEN trunc(SYSDATE,'MM') AND last_day(trunc(SYSDATE)) +0.9999  -- 시스템시간의 그달 처음일부터 마지막 일짜 까지.

 

l         겹쳐져 있는 아이템을 구별하여 사용하는 방법

-- 가용하고자 하는 아이템

set_item_property('CONTROL.BM',displayed,property_true);

         set_item_property('CONTROL.BM',enabled,property_true);

        set_item_property('CONTROL.BM',navigable,property_true);

        -- 가용되지 않토록 하는 아이템

        set_item_property('CONTROL.SELECTED',displayed,property_false);

l         겹쳐진 아이템 부분을 하나만 활성화하여 실행 시키고 나머지는 사용되지 않게 한다.

         set_item_property('CONTROL.C_BM',displayed,property_true);

 

         set_item_property('CONTROL.C_BM',enabled,property_true);

        set_item_property('CONTROL.C_BM',navigable,property_true);

l         탭캔버스의 레이블 얻기

FUNCTION get_tab_id RETURN varchar2

IS

           tp_nm   VARCHAR2(30);

           tp_id   TAB_PAGE;

           tp_lb   VARCHAR2(30);

BEGIN

           tp_nm := GET_CANVAS_PROPERTY('C_TAB', topmost_tab_page);  -- 탭캔버스 명칭

           tp_id := FIND_TAB_PAGE(tp_nm); -- 탭페이지 찾기

           tp_lb := GET_TAB_PAGE_PROPERTY(tp_id, label);      --탭페이지의 레이블 구함.          return tp_lb;

 

END      get_tab_id;

 

 

l         검색 버튼을 눌렀을 때 평션 구현 방법

control.find('WHEN-BUTTON-PRESSED'); -- control 패키지에 find프로시져의 parameter로 'WHEN-BUTTON-PRESSED'를 준다.

l         forms_ddl('COMMIT'); 폼상에 commit하는 방법.

l         TEMP파일에 DATA 담는 방법

버튼을 눌렀을 때(WHEN-BUTTON-PRESSED) : control.data_interface('Interface');

---- 인터페이스 버튼을 눌렀을때 temp file에 자료를 수집하는 부분 ----------

-- 아쉬운점) from 보다 to가 작을때 날짜가 잘못 입력됐다는 메세지를 띄웠다면...---

PROCEDURE data_interface(event VARCHAR2) IS

 

BEGIN   

           IF event = 'Interface' THEN      -- 파라미터가 interface일때 temp file에 저장하기 위한 작업

        

         -- Delete Previous Data           

      DELETE FROM  XONTS_ITEM_ORDER_ALLOC_TMP; -- 미리 템프파일을 지움.

       

         fnd_message.debug('Data를 수집중입니다');           

     

      INSERT INTO  XONTS_ITEM_ORDER_ALLOC_TMP  -- loop를 돌지 않아도 select구문에 의해 여러 레코드가 저장됨.

                                              ( BM_CODE

                                               ,BM_NAME

                                               ,ST_CODE

                                               ,ST_NAME

                                               ,PM_CODE

                                               ,PM_NAME

                                               ,PLAN_CODE

                                               ,PLAN_NAME

                                               ,ORDER_QTY

                                               ,ORDER_AMOUNT

                                               ,ALLOC_QTY

                                               ,ALLOC_AMOUNT

                                               ,S_QTY

                                               ,J_QTY

                                               ,INVENTORY_ITEM_ID

                                               ,ITEM_CODE

                                               ,ITEM_DESCRIPTION

                                               ,REQUEST_DATE

                                               ,LINE_ID

                                               ,FLAG

                                               )

                                               SELECT  BM_CODE

                                               ,BM_NAME

                                               ,ST_CODE

                                               ,ST_NAME

                                               ,PM_CODE

                                               ,PM_NAME

                                               ,PLAN_CODE

                                               ,PLAN_NAME

                                               ,ORDER_QTY

                                               ,ORDER_AMOUNT

                                               ,ALLOC_QTY

                                               ,ALLOC_AMOUNT

                                               ,S_QTY

                                               ,J_QTY

                                               ,INVENTORY_ITEM_ID

                                               ,ITEM_CODE

                                               ,ITEM_DESCRIPTION

                                               ,REQUEST_DATE

                                               ,LINE_ID

                                               ,FLAG

                                                 FROM  XONTS_ITEM_ORDER_ALLOCATION  XIOA

                                                WHERE  XIOA.REQUEST_DATE  BETWEEN :control.date_from AND :control.date_to;

      forms_ddl('COMMIT');

         -- 루프를 돌지 않아도 데이터가 수집된다.

         fnd_message.debug('Data 수집을 완료하였습니다, 조회 버튼으로 데이터를 조회하세요');

    ELSE

      fnd_message.debug('Invalid event passed to control.data_interface - '||event);

    END IF;

   

EXCEPTION

         WHEN others THEN

           ROLLBACK;    

END data_interface;

 

l         스택캔버스로 이루어진 탭캔버스를 이동하는 방법.

IF :CONTROL.tab_id = 'Brand' THEN -- BRAND 탭이 눌러 졌을때

        Hide_View('S_ST');  -- 스택 캔버스를 숨긴다.

                    Hide_View('S_PM');

                    Hide_View('S_PL');

                    Show_View('S_BM');         

        go_block('XONTS_ORDER_ALLOC_BM_V'); 

     

      ELSIF :CONTROL.tab_id = '전략단위' THEN

         Hide_View('S_BM');

                    Hide_View('S_PM');

                    Hide_View('S_PL');

                    Show_View('S_ST');         

        go_block('XONTS_ORDER_ALLOC_ST_V');

        

      ELSIF       :CONTROL.tab_id = '분석단위' THEN

         Hide_View('S_ST');

                    Hide_View('S_BM');

                    Hide_View('S_PL');

                    Show_View('S_PM');         

        go_block('XONTS_ORDER_ALLOC_PM_V');

 

      ELSIF :CONTROL.tab_id = '세부분석' THEN

         Hide_View('S_ST');

                    Hide_View('S_PM');

                    Hide_View('S_BM');

                    Show_View('S_PL');         

        go_block('XONTS_ORDER_ALLOC_PL_V');

        

      END IF;    

 

l         메시지를 CLEAR하는 것 : fnd_message.clear;

l         사용자 id를 알 수 있는 방법 : nvl(FND_PROFILE.VALUE('USER_ID'), -1);

l         do_key('clear_block'); 해당 블록을 CLEAR

DO_KEY('EXECUTE_QUERY'); -- 쿼리의 실행

l         메시지를 문자열로 뿌려 주는 것 :

fnd_message.set_string('업로드할 텍스트 파일은 헤더를 제외한 데이터 만으로 구성되어야 합니다.'||chr(10)||

                       'Excel에서 작업 후 저장 시 파일 형식을'||chr(10)||'[텍스트 (탭으로 분리) (*.txt)]'||

                       ' 로 선택하여 저장하면 됩니다.'||chr(10)||

                       '계속 하시겠습니까?');

if fnd_message.QUESTION('YES','NO',null, 1, 2, 'question') = 2 then  -- 1계속,2중단

    null;

else 

    FILE_HANDLE.FILE_UPLOAD ;  -- 업로드할 창이 뜬다. 

end if;                       

 

FND_MESSAGE.SET_STRING('배송희망 일자를 선택 하세요');

FND_MESSAGE.SHOW;

 

l          fnd_message.debug('File ID를 가져오는 중 에러가 발생하였습니다.'||chr(10)||

                                        '담당자에게 문의하여 주십시오'); chr(10) => line feed.

l          forms_ddl('commit');

l          기존에 만들어진 데이터블록에서 새로운 데이터블록 및 뷰에 컬럼을 추가 시켜 만들어진 새로운 뷰일 때 항상 데이터블록 위자드를 새롭게 만들어야 한다.

 

SITE_USE_ID, SITE_USE_CODE, BILL_TO_SITE_USE_ID,LOCATION

1        2066     SHIP_TO             1498  홈플러스신갈S

2        3316     SHIP_TO             2721  홈플러스신갈S

3        1498     BILL_TO                           홈플러스신갈S

4        2721     BILL_TO                           홈플러스신갈S

l          TEAM > PART(일종의 지역별로 이해) > 매장(분당 이마트) > ITEM

l          SELECT 구문의 WHERE조건절 구성시 WHERE AND 문제를 해결하기위해서 => v_where varchar2(2000) := '1=1'; 

l          다른 데이터블록에 존재하는 필드의 SUM하는 방법

n         SUM하는 컨트롤 데이터블록에 ‘QUERY ALL RECORDS : YES’, ‘SINGLE RECORD : YES’, ‘DATABASE : NO’,

n         SUM 당하는 데이터블록에 ‘QUERY ALL RECORDS : YES’, ‘SINGLE RECORD : NO’, ‘DATABASE : YES’,

l          PL/SQL에서 SELECT 구문을 사용한 뒤 간단히 데이터를 변경코자 할 때 (VIEW는 안됨), 자물쇠를 열고서 자료를 변경하고 체크 버튼을 누르면 적용된다.

SELECT *
FROM xonts_sales_persons_v
WHERE team_desc =
'식품_ECR광주지점’
FOR UPDATE

l         날짜 뿐만 아니라 시간단위까지 조회

WHERE  XIOA.REQUEST_DATE  BETWEEN TO_DATE(TO_CHAR(:control.date_from, 'YYYYMMDD')|| ' 000000', 'YYYYMMDD FMHH24MISS') AND    TO_DATE(TO_CHAR(:control.date_to, 'YYYYMMDD')|| ' 000000', 'YYYYMMDD FMHH24MISS');   -- 조회되는 일자를 하루 더하여 출고일자로 조회.

-         TO_CHAR(TO_DATE(:xlge_import.due_time,'HH24MISS'),'HH24MISS')

-         년월일시간으로 추려본 조건  

 last_update_dt <  to_date(200610121200,'yyyymmdd hh24mi');

 

l         SERIAL NO를 구함. (개인 사용자에게 SERIAL NO를 부여하여 멀티 사용이 가능 토록 한다.

            SELECT SERIAL#

            INTO   V_SERIAL_NO

            FROM   V$SESSION

            WHERE  AUDSID = USERENV('SESSIONID');

l         QUERY문의 WHERE 조건절을 구성

-- C_PL 

      IF  :CONTROL.C_PL IS NOT NULL THEN 

           app_query.reset('XONTS_ORDER_ALLOC_PL_V');       

           app_query.append('XONTS_ORDER_ALLOC_PL_V', 'PL_NAME  = :control.c_pl AND SERIALNO = :control.serial_no');

           app_query.reset('XOA_PL_V');  -- XONTS_ORDER_ALLOC_PL_D_V        

           app_query.append('XOA_PL_V', 'PL_NAME  = :control.c_pl AND SERIALNO = :control.serial_no');

      ELSE

           app_query.reset('XONTS_ORDER_ALLOC_PL_V');       

           app_query.append('XONTS_ORDER_ALLOC_PL_V', 'SERIALNO = :control.serial_no');

             

           app_query.reset('XOA_PL_V');  -- XONTS_ORDER_ALLOC_PL_D_V        

           app_query.append('XOA_PL_V', 'SERIALNO = :control.serial_no');

      END IF;  

SERIAL NO는 조회화면에 접속할 때 마다 UNIQUE하게 데이터를 제공한다.

l         오라클 애플리케이션에서 소스를 파악하는 방법

실제 애플리케이션 상의 화면에 보이는 경로는 실행파일의 경로이다. 그러나 실제 소스의 위치를 파악하는 것은 화면 경로명이 아니라 파일의 명칭을 보면 모듈별로 관리되기 때문에 파일명을 보고 유추하여 파악할 수 있다.

) 화면 경로 : /usere/oraprod/prodappl/fnd/11.5.0/forms/KO/XONTSPF006.fmx

실제 소스 경로 :  /usere/oraprod/prodappl/xonts/11.5.0/forms/US

 

l         Function을 이용해서 쿼리로 이용.

CREATE OR REPLACE FUNCTION xonts_get_org_code_func( p_org_id IN NUMBER
                   )
                   RETURN varchar2
IS
    v_org_code varchar2(
30);
BEGIN
    SELECT organization_code           

    INTO   v_org_code
    FROM   org_organization_definitions
    WHERE  organization_id = p_org_id
    ;
   
    RETURN v_org_code;
END;

l         Function을 이용한 view 구성

select xonts_get_org_CODE_func(RECEIVING_ORG_ID) TO_ODMA¢°i,
       xonts_get_org_name_func(RECEIVING_ORG_ID) TO°AA¡º´,
       nvl(xonts_get_org_CODE_func(SOURCING_ORG_ID),SOURCING_ORG_ID) ODMA¢°i,
       nvl(xonts_get_org_name_func(SOURCING_ORG_ID),xonts_get_vendor_name_func(SOURCING_ORG_ID)) °AA¡¸i,
       ORDERED_QUANTITY ¼o·®
from  XONTS.XONTS_DRP_SHIP_REQ_IF_ETC

 

l         VIEW만들 때 Function을 이용해서 쿼리 문 작성

CREATE OR REPLACE VIEW XONTS_MICHUL_TEAM_V AS
SELECT XONTS_GET_ACCOUNT_PART(
'TN',oola.salesrep_id) TEAM_DESC --ÆA¸i
      ,XONTS.BM_NAME BM
      ,XONTS.ITEM_CODE C°¸nAUμa
      ,XONTS.ITEM_DESCRIPTION C°¸n¸i     
      ,XONTS.ORDER_QTY AO¹®CoE²
      ,XONTS.ALLOC_QTY ¹eA¡CoE²          
      ,OOLA.SHIPPED_QUANTITY AaCICoE²
      ,XONTS.REQUEST_DATE Aa°iAI
FROM   XONTS_ITEM_ORDER_ALLOCATION XONTS
-- ITEM_CODE, ITEM_NAME, ORDER_QTY(AO¹®¼o·®), ¹eA¡CoE²
      ,oe_order_lines_all oola
WHERE  OOLA.LINE_ID = XONTS.LINE_ID

 

l         위의 쿼리 문에서 호출되어지는 function

l         CREATE OR REPLACE FUNCTION XONTS_GET_ACCOUNT_PART
                                                            (p_gubun IN VARCHAR2,
                                                             p_sales_person_id  IN NUMBER ) RETURN varchar2 IS

  RESULT                                               VARCHAR2(
100);
  V_TEAM_CODE                               VARCHAR2(
100);
  V_TEAM_NAME                                VARCHAR2(
100);
  V_PART_CODE                                VARCHAR2(
100);
  V_PART_NAME                                VARCHAR2(
100);

BEGIN

  SELECT FFV.FLEX_VALUE TEAM_CODE,
          FFV.DESCRIPTION TEAM_NAME,
          SP.SALESREP_ID PART_CODE,
          SP.NAME PART_NAME
  INTO  V_TEAM_CODE,
              V_TEAM_NAME,
              V_PART_CODE,
              V_PART_NAME
    FROM   JTF_RS_SALESREPS        SP
          ,GL_CODE_COMBINATIONS    GCC
          ,FND_FLEX_VALUES_VL      FFV
          ,FND_ID_FLEX_SEGMENTS_VL FIF
    WHERE      SP.SALESREP_ID              = p_sales_person_id
    AND    GCC.CODE_COMBINATION_ID     = SP.GL_ID_REV
    AND    FFV.FLEX_VALUE              = GCC.SEGMENT2
    AND    FFV.FLEX_VALUE_SET_ID       = FIF.FLEX_VALUE_SET_ID
    AND    FIF.ID_FLEX_CODE            =
'GL#'
    AND    FIF.APPLICATION_ID          =
101
    AND    FIF.APPLICATION_COLUMN_NAME =
'SEGMENT2'
    AND    FFV.FLEX_VALUE_SET_ID       =
1010398 ;

    IF p_gubun =
'TC'  THEN     -- team code
           RESULT  := V_TEAM_CODE ;
    ELSIF  p_gubun =
'TN'  THEN     -- team name
           RESULT  := V_TEAM_NAME ;
    ELSIF  p_gubun =
'PC'  THEN     -- part code
           RESULT  := V_PART_CODE;
    ELSIF  p_gubun =
'PN'  THEN     -- part name
           RESULT  := V_PART_NAME ;
    END IF;

  RETURN(RESULT);

END XONTS_GET_ACCOUNT_PART;

l         전체 레코드 개수 구하기

CUR_COUNT  NUMBER(4) := 0;

 

GO_BLOCK(‘DEPT’);

LAST_RECORD;

CUR_COUNT := TO_NUMBER(:SYSTEM.CURSOR_RECORD);

FOR  I  IN 1..CUR_COUNT LOOP

~~~~

END LOOP;

l         CURSOR의 루프돌기

OPEN  CUR_PROD_PLAN;
    i :=
1;
    LOOP
        FETCH CUR_PROD_PLAN INTO        
          X_INPUTDATA_CHECK_TBL(i).YYYYMMDD
        , X_INPUTDATA_CHECK_TBL(i).FACTORY_CD
        , X_INPUTDATA_CHECK_TBL(i).PROD_FG
        ;
        EXIT WHEN CUR_PROD_PLAN%NOTFOUND; 
        i:= i +
1;
    END LOOP;

CLOSE CUR_PROD_PLAN;

 

 

l         트리거 중 WHEN-NEW-BLOCK-INSTANCE에 아래의 코딩을 하면 상위단의 툴바 중 삽입 아이콘이 비활성화 된다.

APP_MENU.SET_PROP('FILE.NEW',ENABLED,PROPERTY_ON);       -- 툴바 아이콘 ENsabled

l         WHEN_BUTTON_PRESS버튼이 눌러졌을 때 트리거

IF (EVENT = 'WHEN-BUTTON-PRESSED') THEN

l         FORMS상의 COMMIT명령어.

FORMS_DDL('COMMIT');

l          버튼 조회시 프로시저 관리

버튼 눌렀을 때 : MAIN.QUERY_BUTTON('WHEN-BUTTON-PRESSED');

1) MAIN 패키지상의 프로시져

PROCEDURE QUERY_BUTTON(EVENT VARCHAR2) IS

    /* 조회 버튼 클릭시 */

    BEGIN

        /* MAIN TB를 조회 */

   -. 조회 버튼을 눌렀을시 조회문의 종류 : APP_FIND.FIND('XONTS_MD_MASTERS_V');

STANDARD_QUERY.DO_QUERY;       

    END QUERY_BUTTON;

l         뷰상의 날짜에 for loop를 돌면서 변수j를 붙인뒤 ‘_QTY'를 만든다. 즉 DAY1_QTY라고 만들고 그걸 데이터블록의 컬럼(필드)에 셋팅한다.

display_item('XOMK_PROD_PLAN_V.DAY'||to_char(j)||'_QTY','SET');        

l         랭킹 구하기

SELECT SHIPMENT_PRIORITY
       ,INVENTORY_ITEM_ID
       ,RANK() OVER (ORDER BY ORDERED_QUANTITY DESC) AS RK
FROM XONTS_BATCH_ALLOCATIONS ;

l         날짜 형식

1. BETWEEN  TO_DATE('20060925'|| ' 000000', 'YYYYMMDD FMHH24MISS')
     AND      TO_DATE(
'20060926'|| ' 235959', 'YYYYMMDD FMHH24MISS')

2. XIOA.REQUEST_DATE BETWEEN TO_DATE(TO_CHAR(:CONTROL.DATE_FROM,'YYYY-MM-DD') || ' 000000','YYYY-MM-DD FMHH24MISS')  AND TO_DATE(TO_CHAR(:CONTROL.DATE_TO,'YYYY-MM-DD') || ' 235959','YYYY-MM-DD FMHH24MISS');

3. 오늘의 날짜로 조회하고 싶을 때 :

SELECT * FROM pm_post_conv_inf
WHERE create_date > trunc(SYSDATE);

4. 그 해의 1월 1일 :

select TRUNC(SYSDATE,'yyyy') from dual;

5. to_date(j,'DD') => J 숫자에 대해 ‘DD’는 ‘일’을 의미하며 날짜 형태로 변환

6. 날짜와 날짜를 뺀다. 그런데 char형태로 형변환을 해서 차이를 구함.

to_char(sysdate,'yyyymmdd') - (:FIND_CONTROL.YYYYMM||to_char(to_date(j,'DD'),'DD') )

7. 해당 월의 마지막 일짜를 구함. : LAST_DAY(SYSDATE)

l         데이터 블록의 위자드를 사용하지 않고 필드에 값을 기입하는 방법

  FOR S1 IN (SELECT /*+ no_merge(tnp) no_push_pred(tnp) */ TNP.TEAM_CODE||' / '||TNP.TEAM_NAME TEAM

                   ,TNP.PART_CODE||' / '||TNP.PART_NAME PART

                   ,HCS_BILL_TO.SITE_USE_ID||' / '||HCS_BILL_TO.LOCATION SITE

                   ,SUM(NVL(OOL.ORDERED_QUANTITY, 0))     UPDATE_QUANTITY

                   ,SUM(NVL(OOL.ORDERED_QUANTITY * OOL.UNIT_LIST_PRICE, 0))

                         - SUM(NVL(DECODE(OOL.ATTRIBUTE6, '2', OOL.ORDERED_QUANTITY * OOL.UNIT_SELLING_PRICE), 0))

                     - SUM(NVL(DECODE(OOL.ATTRIBUTE6, '1', OOL.ORDERED_QUANTITY * OOL.UNIT_SELLING_PRICE), 0))

                                                         UPDATE_AMOUNT

                   ,SUM(NVL(XBA.ORDERED_QUANTITY, 0))     CLOSE_QUANTITY

                   ,SUM(NVL(XBA.ORDERED_QUANTITY * OOL.UNIT_LIST_PRICE, 0))

                         - SUM(NVL(DECODE(OOL.ATTRIBUTE6, '2', OOL.ORDERED_QUANTITY * OOL.UNIT_SELLING_PRICE), 0))

                     - SUM(NVL(DECODE(OOL.ATTRIBUTE6, '1', OOL.ORDERED_QUANTITY * OOL.UNIT_SELLING_PRICE), 0))

                                                       CLOSE_AMOUNT

             FROM   OE_ORDER_HEADERS_ALL OOH

                   ,OE_ORDER_LINES_ALL   OOL

                   ,OE_TRANSACTION_TYPES_TL  OTT

                   ,OE_TRANSACTION_TYPES_ALL OTA

                   ,HZ_CUST_SITE_USES_ALL    HCS

                   ,HZ_CUST_SITE_USES_ALL    HCS_BILL_TO

                   ,XONTS_BATCH_ALLOCATIONS  XBA

                   ,(SELECT /*+ INDEX(GCC GL_CODE_COMBINATIONS_U1) */ FFV.FLEX_VALUE        TEAM_CODE

                           ,FFV.DESCRIPTION       TEAM_NAME

                           ,JRS.RESOURCE_ID

                           ,JRS.SALESREP_ID       PART_CODE

                           ,JRS.SALESREP_NUMBER

                           ,JRS.NAME              PART_NAME

                           ,JRD.ATTRIBUTE1

                     FROM   JTF_RS_SALESREPS        JRS

                           ,JTF_RS_DEFRESOURCES_VL  JRD

                           ,GL_CODE_COMBINATIONS    GCC

                           ,FND_FLEX_VALUES_VL      FFV

                           ,FND_ID_FLEX_SEGMENTS_VL FIF

                     WHERE  JRS.RESOURCE_ID             = JRD.RESOURCE_ID

                     AND    JRD.ATTRIBUTE1              = 'OM'

                     AND    GCC.CODE_COMBINATION_ID     = JRS.GL_ID_REV

                     AND    FFV.FLEX_VALUE              = GCC.SEGMENT2

                     AND    FFV.FLEX_VALUE_SET_ID       = FIF.FLEX_VALUE_SET_ID

                     AND    FIF.ID_FLEX_CODE            = 'GL#'

                     AND    FIF.APPLICATION_ID          = 101

                     AND    FIF.APPLICATION_COLUMN_NAME = 'SEGMENT2'

                     AND    FFV.FLEX_VALUE_SET_ID       = 1010398

                    )                       TNP    -- 팀name과 part name

             WHERE  OOH.HEADER_ID = OOL.HEADER_ID

             AND    OOH.ORDER_TYPE_ID       = OTT.TRANSACTION_TYPE_ID

             AND    OTT.TRANSACTION_TYPE_ID = OTA.TRANSACTION_TYPE_ID

             AND    OOL.SHIP_TO_ORG_ID      = HCS.SITE_USE_ID

             AND    HCS.BILL_TO_SITE_USE_ID = HCS_BILL_TO.SITE_USE_ID

             --AND    OOL.INVOICE_TO_ORG_ID   = HCS_BILL_TO.SITE_USE_ID

             AND    OOL.LINE_ID             = XBA.LINE_ID(+)

             AND    TNP.PART_CODE(+)        = HCS_BILL_TO.PRIMARY_SALESREP_ID

             AND    OTT.LANGUAGE            = USERENV('LANG')

             --AND    OOL.ORDERED_ITEM        = NVL(:CONTROL_1.SEGMENT1, OOL.ORDERED_ITEM)

             AND    OOL.ORG_ID              = 165

             AND    OOL.REQUEST_DATE       >= :CONTROL_1.S_DATE

             AND    OOL.REQUEST_DATE       <  :CONTROL_1.E_DATE + 1

             --AND    OOL.REQUEST_DATE       >= TO_DATE('20060630', 'YYYYMMDD')

             --AND    OOL.REQUEST_DATE       <  TO_DATE('20060630', 'YYYYMMDD') + 1

             GROUP BY

                    TNP.TEAM_CODE

                   ,TNP.TEAM_NAME

                   ,TNP.PART_CODE

                   ,TNP.PART_NAME

                   ,HCS_BILL_TO.SITE_USE_ID

                   ,HCS_BILL_TO.LOCATION

            )

  LOOP

         N_CNT := N_CNT + 1;

        

         IF V_TEAM_CHECK = S1.TEAM THEN                               

           :B_MAIN.TEAM := NULL;

         ELSE    

           :B_MAIN.TEAM := S1.TEAM;

         END IF;

         V_TEAM_CHECK := S1.TEAM;

           

         IF V_PART_CHECK = S1.PART THEN    

           :B_MAIN.PART := NULL;

         ELSE

           :B_MAIN.PART := S1.PART;

         END IF;

         V_PART_CHECK := S1.PART;

        

         --:B_MAIN.TEAM := S1.TEAM;

         --:B_MAIN.PART := S1.PART;

         :B_MAIN.SITE := S1.SITE;

         :B_MAIN.UPDATE_QUANTITY := S1.UPDATE_QUANTITY;

         :B_MAIN.UPDATE_AMOUNT   := S1.UPDATE_AMOUNT;

         :B_MAIN.CLOSE_QUANTITY  := S1.CLOSE_QUANTITY;

         :B_MAIN.CLOSE_AMOUNT    := S1.CLOSE_AMOUNT;

         NEXT_RECORD;

  END LOOP;

트리거나 프로그램 유닛에서 FOR LOOP를 이용하여 데이터블록의 필드 값을 표기 (:B_MAIN은 위자드 상의 뷰나 테이블을 의미하는 블록으로 위자드를 사용하지 않고 필드 값을 기입할 수 있다.)

GROUP_ID ( )

설명

GROUP BY의 확장으로 인하여 같은 grouping을 나타내는 값이 중복되어 결과 집합(result set)에 포함될 수 있으며, 이 때 중복된 그룹들을 구별하기위해 처음으로 중복되어 나타나는 행에 대하여 GROUP_ID 함수는 0을 반환하고, 나머지 경우에 대하여 1의 값을 반환한다. 그러므로 이 함수는 질의 결과에서 중복된 groupings를 필터링하는데 유용하다.

 

GROUPING_ID ( expression [, expression ]... )

설명

임의의 질의는 특정 행에 대한 GROUP BY level을 알기 위해 GROUPING 함수에 대한 정보를 반환해야만 한다. GROUPING_ID 함수는 특정 expression set을 인자로 각 열이 grouping 되었는지를 알기 위해 각 열(expression)에 대해 2 bit의 집합을 취하여, 각각의 bit concatenate하고 10진 값으로 반환한다.

보통 GROUPING SETS 확장에 의한 질의의 결과는 grouping 열에 NULL 값을 가질 수 있다. 이는 원래의 열 값이 NULL 인 경우와 구분하여야 하는데, 이런 경우 GROUPING_ID 함수를 사용하여 행 필터링을 수월하게 할 수 있다.

GROUPING_ID 함수는 단지 SELECT -ROLLUP 또는 CUBE GROUPING 함수와 같은 GROUP BY 확장을 포함하는- 에서만 적용할 수 있다.

l         ROLLUP

ROLLUP절에 명시된 컬럼의 순서(계층)에 따라 부분합을 계산 한다.

l         윈도우 포지션 지정.

APP_WINDOW.SET_WINDOW_POSITION( 'SHIP_SEPARATE', 'CENTER' ); -> SHIP_SEPARATE : 캔버스

l         id 가져오는 방법

FND_PROFILE.GET('USER_ID', :PARAMETER.P_USER_ID); -- :parameter는 네비게이터의 파라미터 부분에 설정.

l         해당 USER SECURITY SORT CD를 찾는다.

  FND_PROFILE.GET('KMS_SECURITY_ORG', :PARAMETER.P_PROFILE_OPTION_VALUE);

l         Organization_id

:parameter.OPERATING_UNIT_ID := TO_NUMBER( FND_PROFILE.VALUE('ORG_ID'));

l         Set of books id 셋팅

:parameter.set_of_books_id   := TO_NUMBER( FND_PROFILE.VALUE('GL_SET_OF_BKS_ID'));

l          SESSION ID 셋팅

:PARAMETER.P_SESSION_ID := USERENV('SESSIONID');

l         DB SESSION ID

FND_PROFILE.GET('DB_SESSION_ID', :PARAMETER.P_SESSION_ID);

l         URL 셋팅

V_STRING := FND_WEB_CONFIG.WEB_SERVER;  -- 웹어플리케이션의 url정보 (http://lgeerpase8q.lge.com:8008)

--       V_STRING := 'http://lgeerpase0q.lge.com:8003/';  --DEV4

--       V_STRING := 'http://lgeerpase0q.lge.com:8006/';  --OPR3

      V_STRING := V_STRING||'cgi-bin/excel_import_ui_xls.cgi?'||

                          'session_id='||TO_CHAR(:PARAMETER.P_SESSION_ID)||

                          '&user_id='||TO_CHAR(:PARAMETER.P_USER_ID);

-- WEB 화면을 실행              

    WEB.SHOW_DOCUMENT(V_STRING,'_SELF');

l         주로 COUNT함수는 대상의 존재여부를 체킹할 때 사용한다. 카운드하여 0 이라면 존재하지 않고 그외의 숫자는 값이 존재한다.

select count(*)

    into   v_count

    from    xlge_import

        where  created_by = :parameter.p_user_id

  and    session_id = :parameter.p_session_id

 

FND_MESSAGE.SET_NAME('FND', '확인 버튼을 누르면 화면에 나타납니다.');

FND_MESSAGE.SHOW;

FND_MESSAGE.ERROR; 위의 두 메시지 차이점 비교해봐라 ????????????????

l         PROGRAM UNIT PACKAGE사용방법 : 패키지명.프로시저/평선 예)FIND_CONDTROL.POPULATE_LIST_ITEM

 

 

DML

l          delete from 테이블명 where 조건

l          update 테이블명 set 업데이트할 필드 = where 조건

l         v_cursor := TO_NUMBER(:SYSTEM.CURSOR_RECORD); -- 현재 커서가 있는 레코드의 위치 수

 

PL SQL정리

 

V_empno      emp.empno%type;

T_emp        EMP%rowtype

If SQL%NOTFOUND then

 

l          Package

 

Package body 스팩에 쓰여진 프로시져는 package specification에서 같이 선언해야 한다.

First we created the package specification.

CREATE OR REPLACE PACKAGE test AS -- package spec
    TYPE list IS VARRAY(25) of NUMBER(3);

    PROCEDURE hire_employee (emp_id INTEGER, name VARCHAR2);
    PROCEDURE fire_employee (emp_id INTEGER);
    PROCEDURE raise_salary (emp_id INTEGER, amount REAL);
END test;
/

Then we created the package body.

CREATE OR REPLACE PACKAGE BODY test AS -- package body
    PROCEDURE hire_employee (emp_id INTEGER, name VARCHAR2) IS
    BEGIN
        INSERT INTO employee VALUES (emp_id, name, 1000);
    END hire_employee;

    PROCEDURE fire_employee (emp_id INTEGER) IS
    BEGIN
        DELETE FROM employee WHERE empno = emp_id;
    END fire_employee;

    PROCEDURE raise_salary (emp_id INTEGER, amount REAL) IS
    BEGIN
        DBMS_OUTPUT.PUT_LINE('Increase Salary :' || to_char(amount));
        UPDATE employee SET sal = sal + amount WHERE empno = emp_id;
    END raise_salary;
END test;

/

의문) 테스트 스크립트 생성?

exec test111('파라미터1',파리미터2);

l          dbms_output.put_line(‘1등 찬희’);

위의 스크립트를 실행 시키기 위해서는 Set ServerOutput On Size 10000; 를 사용.

 

 

프로시저 실행시 테스트 윈도우에서 점검 -> 테스트 스크립이 생성된다.

 

l         FND_FILE.PUT_LINE( fnd_file.log, 'Unexpected Error!!! '); -- 파일에 스트링 적기.

-. 에러 시 빠져 나감. : RAISE FND_API.G_EXC_UNEXPECTED_ERROR;

 

l         Select된 정보를 바로 insert해서 사용하는 방법

insert into pm_post_conv_inf p     ( SYSTEM_ID
    , TABLE_NAME
    , SEQ
    , ADDR
    , KEY1
    , REQUEST_FG
    , ANSWER_FG
    , CREATE_DATE
    )
    select
'LGEERPDSE' SYSTEM_ID

         , 'XOMK_SHIP_TO' TABLE_NAME
         , XOMK_POSTCODE_CONV_TEMP_S.NEXTVAL SEQ
         , s.address1||
' '||s.address2 addr     

         , s.site_id KEY1
         ,
'N' REQUEST_FG
         ,
'N' ANSWER_FG
         , SYSDATE
    from   xomk_ship_to s                       

where  s.post_id in
           (select p.addr_seq
            from   xomk_pm_post_inf p          

            where  p.use_fg = 'N'              

            and    p.expire_dt is not NULL
            and    p.job_type =
'U' )

and    not exists ( select key1  from   pm_post_conv_inf ppc   where  ppc.system_id = 'LGEERPDSE'                              and    ppc.table_name = 'XOMK_SHIP_TO'  and  ppc.key1 = s.site_id  and    ppc.applied_flag = N');

l         로그 파일보는 방법 : 오라클 애플리케이션에서보기 -> 요청 -> 요청찾기에서 로그 파일의 내역을 볼 수 있다.

l         EXIT WHEN cur_new_zipcode%NOTFOUND;  -- 커서의 데이터가 없을 때 바로 빠져 나감..

l         동의어 사용법 : create or replace synonym APPS.VI_LI_RDCORDEAGLE
  for VI_LI_RDCORDEAGLE@DL_LGETMSSE2S_DBPLOX;

l         FND_CONCURRENT.SET_COMPLETION_STATUS('WARNING','');

l         SELECT *

FROM  oe_order_lines_all

WHERE ROWNUM < 10;

l          select transaction_date, order_line_id, transaction_id, ERROR_DESCRIPTION, reflect_yn, SHIPPED_QUANTITY                             
from   iinvk_shipping_txn_if                     
where  reflect_yn  between
'A' and 'M'           
and    transaction_type_code =
'1'               
union all                                         
select transaction_date, order_line_id, transaction_id, ERROR_DESCRIPTION, reflect_yn, SHIPPED_QUANTITY                                                           
from   iinvk_shipping_txn_if                     
where  reflect_yn  between
'O' and 'X'           
and    transaction_type_code =
'1';

l          윈도우의 위치 지정 : APP_WINDOW.SET_WINDOW_POSITION( 'SHIP_SEPARATE', 'CENTER' );

l          사용자 프로파일 구하기 : FND_PROFILE.GET('USER_ID', :PARAMETER.P_USER_ID);

l          세션 아이디 생성 : :PARAMETER.P_SESSION_ID := USERENV('SESSIONID');

l          URL을 생성

        V_STRING := FND_WEB_CONFIG.WEB_SERVER;

--         V_STRING := 'http://lgeerpase0q.lge.com:8003/';  --DEV4

--         V_STRING := 'http://lgeerpase0q.lge.com:8006/';  --OPR3

    V_STRING := V_STRING||'cgi-bin/excel_import_ui_xls.cgi?'||

                          'session_id='||TO_CHAR(:PARAMETER.P_SESSION_ID)||

                          '&user_id='||TO_CHAR(:PARAMETER.P_USER_ID);

l         프로시저에서 레코드타입의 변수를 만들 때 : spec에서 생성 하고 body에서 이용한다.

TYPE INPUTDATA_CHECK_REC_TYPE IS RECORD (
      YYYYMMDD              XOMK_PROD_PLAN_IF.YYYYMMDD%TYPE
    , FACTORY_CD            XOMK_PROD_PLAN_IF.FACTORY_CD%TYPE
    , MODEL_CD              XOMK_PROD_PLAN_IF.MODEL_CD%TYPE
    , JEBUN                 XOMK_PROD_PLAN_IF.JEBUN%TYPE
    , LINE                  XOMK_PROD_PLAN_IF.LINE%TYPE
    , JEBUN_QTY             XOMK_PROD_PLAN_IF.JEBUN_QTY%TYPE
    , PRODUCT_QTY           XOMK_PROD_PLAN_IF.PRODUCT_QTY%TYPE
    , MARKET_TP             XOMK_PROD_PLAN_IF.MARKET_TP%TYPE
    , LAST_UPDATE_ID        XOMK_PROD_PLAN_IF.LAST_UPDATE_ID%TYPE
    , LAST_UPDATE_DT        XOMK_PROD_PLAN_IF.LAST_UPDATE_DT%TYPE
    , PROD_FG               XOMK_PROD_PLAN_IF.PROD_FG%TYPE
    );
  TYPE INPUTDATA_CHECK_TBL_TYPE IS TABLE OF INPUTDATA_CHECK_REC_TYPE
  INDEX BY BINARY_INTEGER;

-. 바디에서 스펙에 선언한 레코드변수 타입을 아래와 같이 새로운 변수로 선언하여 사용할 수 있다.

X_INPUTDATA_CHECK_TBL    INPUTDATA_CHECK_TBL_TYPE;
    X_INPUTDATA_CHECK_REC    INPUTDATA_CHECK_REC_TYPE;

 

n          TABLE TYPE을 정의

TYPE issue_no_tbl IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER ;

 

TYPE test_record IS RECORD(
     header_id          oe_order_headers_all.header_id%TYPE
   , open_flag          oe_order_headers_all.open_flag%TYPE
  );
TYPE curtype IS REF CURSOR RETURN test_record;

TYPE tbltype IS TABLE OF test_record INDEX BY BINARY_INTEGER;

TYPE SalesOrderCurType IS REF CURSOR RETURN sales_order_record ;

 

테이블 변수의 초기화 : G_msg_tbl.DELETE;

 

l         substr(ord_no,instr(ord_no,'-')+1) : instr ord_no중에서 ‘-‘인 것의 위치를 찾아서 ‘+1’그 다음 위치부터 전부 다 가져와라는 의미

l         전화번호상에 053-234-1234라면 ‘-‘를 1번째 위치부터 찾아서 1번째 ‘-‘이 보이는 위치의 값을 반환 INSTRB(XVL.RECEIVER_TEL_NO,'-',1,1)

l         select substr(ool.shipping_method_code, -2, 1)
from  oe_order_lines_all ool;

=> -2는 뒤에서 두번째를 의미, 1은 뒤에서 한자리를 의미하며 1은 한글자를 가지고 와라는 의미

l         EXIT WHEN CUR_VI_LI_CDCORDEAGLE%NOTFOUND;

l         FOR i IN P_INPUTDATA_CHECK_TBL.FIRST .. P_INPUTDATA_CHECK_TBL.LAST LOOP

~~~~~   end loop; i는 변수를 선언한 뒤 ‘0’으로 초기화

l         Function 사용법

FUNCTION GET_WARE_CHECK_FUNC  ( p_ord_num       IN VARCHAR2

                  ) RETURN VARCHAR2 IS
                  v_ware_check               varchar2(
30);
  BEGIN
    SELECT OTA.ATTRIBUTE2 

INTO   v_ware_check
                  FROM   oe_transaction_types_all ota
                       , oe_transaction_types_tl  otl
                       , oe_order_headers_all     ooh
                  WHERE  ota.attribute1          =
'KMS'
                  AND    ota.transaction_type_id = otl.transaction_type_id
                  AND    otl.LANGUAGE            = USERENV(
'LANG')
                  AND    ooh.order_number        = p_ord_num
                  AND    otl.transaction_type_id = ooh.order_type_id
                  ;
    RETURN(v_ware_check);
  EXCEPTION WHEN OTHERS THEN
         RETURN(
'ERROR');
  END GET_WARE_CHECK_FUNC;

l         레코드 타입의 변수를 만들고 거기에 데이터를 입력시킨 후 그 데이터가 정확한지 검증하기 위해 레코드타입의 변수를 for문을 이용해서 돌린다.

FOR i IN P_INPUTDATA_CHECK_TBL.FIRST .. P_INPUTDATA_CHECK_TBL.LAST LOOP

 

l         해당 USER가 권한이 없는 경우 화면을 열지 못하게 한다.

네비게이터에서 파라미터부분에 P_PROFILE_OPTION_VALUE를 추가하여 사용.

  IF :PARAMETER.P_PROFILE_OPTION_VALUE IS NULL OR V_NO = 0 THEN

     FND_MESSAGE.SET_NAME('FND', '권한이 없습니다.');

     FND_MESSAGE.ERROR;

     RAISE FORM_TRIGGER_FAILURE;

  END IF;          

 

l         PROCEDURE B_MAIN (TRIGGER_NAME IN VARCHAR2,ITEM_NAME IN VARCHAR2 DEFAULT NULL) IS

~~~

B_MAIN('WHEN-BUTTON-PRESSED','EXAMINE');  버튼트리거와 버튼의 이름을 프로시저에 주면 프로시저의 내용에 따라 핸들링을 할 수 있다.

 

l         조직 id

 SELECT FND_PROFILE.VALUE('QP_ORGANIZATION_ID')
FROM   MTL_SYSTEM_ITEMS_B      B; 테이블 명은 아무거나 주어도 상관없다.

l         Case 예문 : case ~ when ~ then ~ else ~ end

decode( ooh.global_attribute1
                       ,
'KMS' , nvl( ooh.attribute16         
                                    , case
                                      when ool.order_source_id in (
1004, 1011, 1014, 1016, 1131, 0) then
xomk_get_dls_mailing_func( ool.line_id ) end
 )

) salesrep_email_addr

l         E_mail id 구현 : v_concat_mail_id := v_cms_code||'@giantmail.lge.com' account code

l         그 달의 마지막 일자의 마지막 시간 구하기

select last_day(trunc(SYSDATE)) +0.9999
from dual;

WHERE a.creation_date BETWEEN trunc(SYSDATE,'MM') AND last_day(trunc(SYSDATE)) +0.9999  -- 그달의 처음부터 마지막까지 구하기

l         CELI : 소수점자리를 무조건 올림한다. => 765.12 : 766, 789.98 : 790
SELECT     CEIL(nvl(DECODE(SIGN(xlr.sale_amt-xlr.minus_amt),
0, 0,
                                                            -
1, 0,
                                                            
1, (xlr.sale_amt-xlr.minus_amt)) *
                                                             xlr.support_rate *
0.01,0))  calculate_incent_amt
FROM   xark_loyalty_results           xlr;

l         Table 2?3 Built-In Functions

Error Number Character Conversion Date Obj Ref Misc

SQLCODE

SQLERRM

ABS

ACOS

ASIN

ATAN

ATAN2

BITAND

CEIL

COS

COSH

EXP

FLOOR

LN

LOG

MOD

POWER

ROUND

SIGN

SIN

SINH

SQRT

TAN

TANH

TRUNC

ASCII

CHR

CONCAT

INITCAP

INSTR

INSTRB

LENGTH

LENGTHB

LOWER

LPAD

LTRIM

NLS_INITCAP

NLS_LOWER

NLSSORT

NLS_UPPER

REPLACE

RPAD

RTRIM

SOUNDEX

SUBSTR

SUBSTRB

TRANSLATE

TRIM

UPPER

CHARTOROWID

CONVERT

HEXTORAW

RAWTOHEX

ROWIDTOCHAR

TO_BLOB

TO_CHAR

TO_CLOB

TO_DATE

TO_MULTI_BYTE

TO_NCLOB

TO_NUMBER

TO_SINGLE_BYTE

ADD_MONTHS

CURRENT_DATE

CURRENT_TIMESTAMP

DBTIMEZONE

EXTRACT

FROM_TZ

LAST_DAY

LOCALTIMESTAMP

MONTHS_BETWEEN

NEW_TIME

NEXT_DAY

NUMTODSINTERVAL

NUMTOYMINTERVAL

ROUND

SESSIONTIMEZONE

SYSDATE

SYSTIMESTAMP

TO_DSINTERVAL

TO_TIMESTAMP

TO_TIMESTAMP_LTZ

TO_TIMESTAMP_TZ

TO_YMINTERVAL

TZ_OFFSET

TRUNC

DEREF

REF

VALUE

TREAT

BFILENAME

DECODE

DUMP

EMPTY_BLOB

EMPTY_CLOB

GREATEST

LEAST

NLS_CHARSET_DECL_LEN

NLS_CHARSET_ID

NLS_CHARSET_NAME

NVL

SYS_CONTEXT

SYS_GUID

UID

USER

USERENV

VSIZE

 

스탠더드에서 제공하는 조직 id코드

SELECT fnd_profile.value('QP_ORGANIZATION_ID')
FROM DUAL; -- 테이블 명은 아무거나 넣어도 상관없음

l         프로시저에서 사용하는 in, out 파라미터, p_var과 p_msg두개의 변수를 받아 p_var로 반환

PROCEDURE to_msg( p_var IN OUT VARCHAR2, p_msg IN VARCHAR2) IS
BEGIN
  p_var := p_var || p_msg ;
END;

 

l         DELETE_PROC ( P_RESULT   => V_RESULT ); 파라미터를 P_RESULT를 넘겨 주고 그 결과를 V_RESULT에 넣는다.

 

FIND_LOV : Searches the list of LOVs and returns an LOV ID

예제) PROCEDURE aaA IS

LOV_ID LOV; -- LOV 변수 선언

BEGIN

  LOV_ID := FIND_LOV('LOV_CUSTOMER'); -- LOV_CUSTOMER가 네비게이션의 LOV목록에 만들어져 있다. 그걸 찾고 ID를 반환한다.

l         강제적으로 LOV 만들기(위자드 사용하지 않음)

네비게이션에 LOV부분에 하나를 추가. OBJECT GROUP과 record group(record group에 추가를 하면 자동으로 오브젝트 그룹에도 추가되는게 아닌지)에도 하나를 추가하고 LOV의 속성창에 RECORD GROUP란에 오브젝트그룹에서 만든 걸 맵핑시켜 준다. Filter before display : yes, automatic display : no, automatic refresh : yes, automatic select : yes, automatic skip : yes, automatic position : yes, automatic column with : yes

 

l         FIND_GROUP

리스트 아이템을 찾아 데이터를 뿌린다.  레코드그룹이 존재한다면 record group id를 얻어라.

RG_DEPARTMENT := FIND_GROUP('R_DEPARTMENT');
- RG_DEPARTMENT : 프로시저 위 부분에서 선언한 레코드그룹 변수, 변수 선언 => RG_DEPARTMENT RECORDGROUP;

- 레코드컬럼변수를 선언 => RC_DEPARTMENT   GROUPCOLUMN;

 

 

l         SELECT JRS.SALESREP_ID

        INTO :FIND_CONTROL.L_MARKETER

        FROM JTF_RS_SALESREPS JRS,

             PER_ALL_PEOPLE_F PP,

             FND_USER         FU

       WHERE FU.USER_ID     = :PARAMETER.P_USER_ID

         AND FU.EMPLOYEE_ID = PP.PERSON_ID

         AND JRS.PERSON_ID  = PP.PERSON_ID

         AND TRUNC(SYSDATE) BETWEEN TRUNC(NVL(JRS.START_DATE_ACTIVE, SYSDATE))

                                AND TRUNC(NVL(JRS.END_DATE_ACTIVE, SYSDATE)) ;

 

l         화면을 clear : app_find.clear;

l         POPULATE_GROUP : 주어진 레코드 그룹과 함께 쿼리를 실행하고 그 결과를 성공이냐 또는 실패냐를 반환. 만약 레코드그룹의 쿼리가 성공하면 '0'을 반환하고 그렇지 않으면 오라클 에러번호를 반환, populate_group을 실행하지 않으면 빈 껍데기만 있는 형상이다. 따라서 populate_group을 실행하면 데이터가 레코드변수에 심어지는 역활을 한다.

RG_DEPARTMENT_NO := POPULATE_GROUP(RG_DEPARTMENT);

POPULATE_LIST('FIND_CONTROL.L_DEPARTMENT',RG_DEPARTMENT);

l         POPULATE_GROUP_WITH_QUERY는 사용자가 임의로 만든 query문을 Record_Group에 적용시키는 역할을 합니다.

l         FIND_GROUP('R_DEPARTMENT') : 주어진 이름의 유효한 그룹이 발견됐을때 레코드그룹의 목록을 찾고 그룹id를 반환.

리턴 값을 받아들일 적당한 변수를 선언할 수 있다. 레코드그룹 변수형태로 정의해라.

l         RECORD GROUP이란?

 : Record Group은 Database Table의 Row/Column 구조와 유사한 Oracle Forms

   의 내부적 구조라 할 수 있다.

   즉, 프로그램적으로 그 기능이 Two-Dimensional Array와 같은 역할을 수행하도

   록 해준다. 또한 이는 Column의 총 갯수가 64K를 초과하지 않는 한도 내에서

   Char, Long, Number, Date Type의 Column들을 제공한다.

 

RC_DEPARTMENT   GROUPCOLUMN;

RG_DEPARTMENT   RECORDGROUP;

 

l          R_DEPARTMENT는 Record groups에 선언되어져 있고, select sales_org_nm으로 필드의 데이터를 가져 옴.  RC_DEPARTMENT_NM := FIND_COLUMN('R_DEPARTMENT.SALES_ORG_NM');  -- 리스트 그룹의 컬럼을 찾고 그 ID를 반환

 

l          GET_GROUP_CHAR_CELL 주어진 로우나 컬럼에 의해 레코드 그룹 셀로 인식되어 셀의 값이 varchar2나 long 타입의 값을 반환

DEPARTMENT_NM := GET_GROUP_CHAR_CELL(RC_DEPARTMENT_NM, 1);

 

l           lov상의 FIND_CONTROL.L_DEPARTMENT 상에 RG_DEPARTMENT에서 가져온 레코드의 데이터를 심는다. 그래서 LOV의 형태가 완성 된다.  populate_list : 현재 list의 내용을 제거하고 레코드그룹으로 부터 값들과 함께 표현한다.

    POPULATE_LIST('FIND_CONTROL.L_DEPARTMENT',RG_DEPARTMENT);

 

l          RC_DEPARTMENT도 := FIND_COLUMN('R_DEPARTMENT.SORT_CD'); -- 그룹컬럼변수로 선언 RC_DEPARTMENT, 하나의 컬럼을 찾아서 심는다.

l          Lov 속성setting : SET_LOV_PROPERTY(LOV_ID,GROUP_NAME,'R_CUSTOMER');

l          WHEN-VALIDATE-ITEM : 아이템에 데이터를 입력하고 그 부분을 벗어나면 바로 검증에 들어가서 합당 여부를 점검.

l          테이블이나 뷰가 find로 하면 찾아지는데 쿼리시 나타나지 않을 경우 sysnonym문제이기 때문에 앞에 ‘모듈명.테이블명’으로 조회하면 보인다.

l          DO_KEY(‘EXECUTE_QUERY’);

l         아이템 속성을 지정한다.

app_item_property.set_property('XOMK_CDC_DETAIL_V.HANG_SEPERATION', DISPLAYED,PROPERTY_OFF); -- 비활성화

app_item_property.set_property('XOMK_RDC_DETAIL_V.HANG_SEPERATION', DISPLAYED,PROPERTY_ON);  -- 활성화

l         윈도우 위치를 지정

APP_WINDOW.SET_WINDOW_POSITION( 'XOMK_DETAIL_V', 'CENTER' );

l         타계정 주문 주소 값에 따라 우편번호,상세주소 도 변경 된다.

APP_FIELD.CLEAR_DEPENDENT_FIELDS('XOMK_DEST_TRANS_V.ADDRESS',

                                     'XOMK_DEST_TRANS_V.POSTAL_CODE',

                                     'XOMK_DEST_TRANS_V.DETAIL_ADDRESS',

                                     'XOMK_DEST_TRANS_V.DELI_ORG_ID'

                                    );

l         타계정주문 인도처가 값에 따라 인도처ID 도 변경 된다.

APP_FIELD.CLEAR_DEPENDENT_FIELDS('XOMK_DEST_TRANS_V.SHIP_TO_SITE',

                                     'XOMK_HOUSE_TRANS_V.SHIP_TO_ORG_ID'

                                    );

l         예외처리 구문

EXCEPTION   

     WHEN APP_EXCEPTIONS.RECORD_LOCK_EXCEPTION THEN

          FORMS_DDL('ROLLBACK');

          FND_MESSAGE.DEBUG('수정시 타 작업중 입니다. 재조회 후 수정 처리 하세요');

          RAISE FORM_TRIGGER_FAILURE;  

          Hide_Window('W_HOME_SHIP');

          STANDARD_QUERY.DO_QUERY;

n          STANDARD_QUERY의 패키지를 만들고 DO_QUERY 프로시저를 만들어라.

n          DO_QUERY 프로시저의 내용 중 아래의 내용을 입력

GO_BLOCK('XOMK_PROD_PLAN_V');

          DO_KEY('EXECUTE_QUERY');

 

        

 

l         프로시저의 기본 셋팅

PROCEDURE MAIN_PROC ( errbuf     OUT VARCHAR2
                      , retcode    OUT NUMBER ) IS

 

l         필터(filer)의 내용 추출 : object_name like 'XOMK%'

 

l         테이블의 primary key 삭제  : alter table xomk.XOMK_PROD_PLAN drop primary key;

 

PK 삭제 방법

1.먼저 primary key를 drop하세요.

-> alter table 테이블명 drop primary key;

2.복합key로 다시 primary key를 만드세요.

-> alter table 테이블명 add constraint 인덱스명 primary key(기존컬럼,추가컬럼) 혹 primary key가 없었다면, 바로 2번으로 가능하죠.

그러나 primary key가 이미 있다면 곧바로 추가는 안됩니다.

 

ㅇ 그밖에 ALTER 문법들

1. 칼럼의 내용을 바꾼다. change

-alter table 테이블명 change '원래칼럼이름' '바꿀칼럼이름' '조건들(ex:데이터형이나 디폴트값)';

-alter table test14 change ide id varchar(10) not null default 0;

2. 프라이머리키를 지운다. drop

-alter table 테이블명 drop primary key;

3. 프라이머리키를 만든다. add

-alter table 테이블명 add primary key (칼럼이름)

%%단 데이터가 들어가 있는 경우에 데이터 간에 중복이 있어서는 안된다.%%

4. 데이터의 위치를 바꾼다. modify

-alter table 테이블명 modify '칼럼이름' '데이터형' [after | first '기준칼럼'];

 

l         테이블에 primary key 추가 : alter table xomk.xomk_prod_plan add primary key(yyyymmdd,factory_cd ,model_cd ,jebun, prod_fg); 단 primary key는 null이 포함된 colum은 추가 될 수 없다.

l         컬럼의 속성 변경 : null -> null
alter table xomk.XOMK_PROD_PLAN modify jebun varchar2(
25) not null;

컬럼이 이미 테이터를 가지고 있을 경우 다른 데이터형으로 변경이 불가능합니다.

 

:SYSTEM.TRIGGER_ITEM => 시스템상의 trigger item을 셋팅.

 

l          변수부분에 exception변수형태로 선언 가능

lv_exception_02             EXCEPTION ;     -- lock error

그리고 나중에 lv_exception_02는 RAISE lv_exception_02 ;정의 하여 사용한다.

또한 when lv_exception_02 then

          fnd_file.put_line(fnd_file.log, lv_err_msg); 로 이용한다.

l          lock걸려있는걸 풀어준다. : DBMS_LOCK.RELEASE (gv_lockhandle)

l          Concurrent 실행 table로 부터 자료를 추출할 수 있는 정보 테이블

FND_CONCURRENT_PROGRAMS

FND_CONCURRENT_REQUESTS

l          Sequence no의 자리 수를 지정.

SELECT TRIM (TO_CHAR (XARK_TAX_INVOICES_ALL_S.NEXTVAL, '00000000000')) from dual;

 

TRIM 함수는 문자값의 왼쪽 또는 오른쪽 부분에 정의한 문자값이 존재하면 그 문자를 절삭시키는 기능을 가지고 있습니다. TRIM 함수는 3가지 종류의 기능을 가지고 있습니다.

-먼저,LEADING은 이전의 LTRIM 함수와 동일한 기능을 가지고 있습니다.정의된 컬럼의 값 왼쪽에 해당 문자열이 존재하면 문자값을 절삭시켜서 화면에 출력합니다.

SQL> SELECT ename, TRIM( LEADING 'A' FROM ename ) as TRIM

     FROM emp

     WHERE ename LIKE 'A%' ;

 ENAME                  TRIM

-------------------------

  ALLEN                   LLEN

  ADAMS                  DAMS

-TRAILING은 이전의 RTRIM 함수의 기능을 가지고 있으며 컬럼값의 오른쪽에 존재하는 문자값을 절삭해줍니다. SQL> SELECT ename, TRIM( TRAILING 'N' FROM ename ) as TRIM

         FROM emp

         WHERE ename LIKE '%N' ;

        ENAME            TRIM

      ---------------------

        ALLEN             ALLE

        MARTIN           MARTI

-BOTH는 왼쪽, 오른쪽에 해당 문자열이 있으면 절삭해 주는 기능을 가지고 있습니다.

 

SQL> SELECT ename, TRIM( BOTH 'A' FROM ename ) as TRIM

         FROM emp

         WHERE ename LIKE 'A%' ;

       ENAME          TRIM

     --------------------

       ALLEN           LLEN

       ADAMS          DAMS

->ENAME 컬럼에서 마지막 문자가 'A'인 값은 발견되지 않았고 첫번째 문자가 'A'인

사원은 ALLEN과 ADAMS

 

l          --USER 권한 체크하여 특정메뉴가 보이거나 보이지 않게 처리

    PROCEDURE RESPONSIBILITY_CHK(p_user_id VARCHAR2) IS

    BEGIN

        FOR J IN   (SELECT  b11.program_id,

                            b11.program_name,

                            b11.menu_name||'.'||b11.menu_list_name  menu_name

                    FROM    ESYS02   b11

                    WHERE   b11.program_id  IN (SELECT  b10.program_id

                                                FROM    ESYS03   b10

                                                WHERE   upper(b10.user_id)  =   upper(p_user_id)

                                                AND     b10.enabled_flag    =   'Y'

                                                AND     SYSDATE             BETWEEN nvl(b10.effective_start_date,SYSDATE)

                                                                            AND     nvl(b10.effective_end_date,SYSDATE + 1))

                    AND     b11.enabled_flag    =   'Y'

                    AND     SYSDATE             BETWEEN nvl(b11.effective_start_date,SYSDATE)

                                                AND     nvl(b11.effective_end_date,SYSDATE + 1))

        LOOP

            SET_MENU_ITEM_PROPERTY(J.menu_name,ENABLED,PROPERTY_TRUE);

            SET_MENU_ITEM_PROPERTY(j.menu_name,LABEL,j.program_name);

        END LOOP;

    END RESPONSIBILITY_CHK;

 

 

튜닝(tunning)

대처방안) 프라이머리 키는 null을 포함하는 필드를 가질 수 없다. 그래서 그 필드를 not null로 변경 하려고 하니 이미 데이터가 들어 있는 자료에 대해서는 변경이 불가능 하다. 따라서 unique index를 사용한다.

CREATE UNIQUE INDEX XOMK.테이블명_u1 ON XOMK.테이블명 ( 컬럼1,2,3,4,~ ) tablespace XOMKX;

Unique index : 중복이 없는 프라이머리키를 테이블안에 저장하기 위해서 사용.
 CREATE [UNIQUE] INDEX index-name ON table-name (column-name [DESC] [,column-name [DESC]] ...) ;

 

l          index사용 : 테이블의 인덱스는 6개 이하로 사용. 인덱스 사용시 우리만 사용하는 테이블이면 plan의 상황을 판단해서 인덱스를 사용하고, standard와 extend table이라도 여러 곳에서 사용한다면 index사용을 지양해야 한다. Full scan이 좋은지 index사용이 좋은지는 판단을 잘해야 한다. 데이터가 많지 않을때는 full scan을 사용하고 한다. 인덱스의 종류가 1개의 컬럼일 때 , composition으로 복합된 컬럼을 여러 개 사용할 때가 있다. Index의 내용을 보고 row_id를 찾아 바로 데이터 값이 있는 row로 간다.

n         Index는 key순서를 고려해서 작성하고, 쿼리문 및 DML(Insert, update, delete)도 index순서를 생각해서 조건을 구성해야한다.

n         plan이라는 것은 DB상에 어떻게 접근하겠다는 계획으로 optimiser가 최적의 조건을 구성한다.

n         PROD_FG IS NOT NULL 이와 같은 형태는 비록 index가 정의 되어 있더라도 무용지물(is not null, is null)
NVL(XPPI.COMPLETE_FG,
'N') <> 'Y' 또한 함수를 사용해도 index사용은 무의미.

n         drop index xomk.XOMK_PROD_PLAN_IF_N1;

n         인덱스를 사용하는 것과 사용하지 않는 것은 속도 차이가 많이 난다.
CREATE INDEX XOMK.XOMK_PROD_PLAN_u1 ON XOMK.XOMK_PROD_PLAN ( yyyymmdd, FACTORY_CD,MODEL_CD,JEBUN,PROD_FG ) tablespace XOMKX;

n         pk와 index는 최소한 drop한 다음 생성 시켜야 함.

n         SELECT /*+ Ordered USE_NL(qlh qht msi qpa qll) */

n         Index column에 어떤 가공이 가해지면 index는 사용이 되지 않는다. => full scan을 하게 됨.

예로 데이터형이 변환되었다거나(varchar2인데 number로 사용) 부정조건(!=)-> 긍정형(~~ not exists(select ~~))으로 변환, is null, is not null등이 있다.

n         인덱스가 여러 있을 어떤 하나의 인덱스를 지정할 :

Select /*+ INDEX (인덱스명) */

예제) SELECT /*+ INDEX (RCTL RA_CUSTOMER_TRX_LINES_U1) */

l          qlh qht msi qpa qll 는 테이블의 alias다.

l          조인 메소드

n         NLJ(nested LOOP join)은 테이블이 두개 있을 시 첫번째 테이블을 먼저 스캔하고 연관되는 테이블을 두번째로 연결시켜 JOIN 한다. 테이블의 인텍스들 중에서 데이터가 적거나 전체적인 분포도가 좋은 것, 예를 들면  1,2,3,4,5,6,,,,가 좋은 것, 1,1,1,1,1 이런 건 좋지 못한 것. 그리고 두개의 테이블을 NLJ을 사용 할 때 두개 중 데이터가 적은 것을 Leading table로 사용하는게 performance 측면에 효율적이다.

n         SMJ (Sort merge join)

n         HJ (hash join)

l          먼저 액세스되는 쪽을 driving table, 나중에 조인되는 table을 inner table이라 함.

l          INSERT나 UPDATE는 실행시 LOCK(LOCK은 전체 테이블을 거는 게 아니라 특정 한 LOW를 건다.)을 걸기 때문에 다른 사용자가 접근하기 힘들다. 그러나 SELECT문은 LOCK을 걸지 않는다.

SELECT /*+index (a XARK_CUSTOMER_HISTORY_N2)*/                                                                                              
        MIN(a.customer_history_id) customer_history_id  
--                                                                                
fROM     xark_customer_history a

 

SELECT /*+ LEADING(OLA) USE_NL(OLA VLS VLR) */
              VLS.ORD_LINE_ID,  
              SUM(DECODE(VLS.ORD_CANCEL_YN,
'Y',0,NVL(VLS.SHP_QTY,0))) ORD_QTY,
              SUM(DECODE(VLS.LP_STATUS_TYPE,
'N',0,VLS.SHP_QTY))       SHP_QTY
       FROM   OE_ORDER_LINES_ALL OLA,
              XOMK_VI_LI_SHIP_V VLS,
              XOMK_VI_LI_CDCORDEAGLE_V VLR

Leading은 제일 데이터가 적거나 분포도가 좋은 것을 먼저 검색해서 사용한다는 의미

 

Bind Variable을 사용하기 어려운 경우에는 세션단위에서 parameter를 변경하여 사용한다.

=> alter session set cursor_sharing = force ; alter session set cursor_sharing = exact ;

l         대부분의 In-line view는 Join 문으로 변환이 가능하며, In-line view에서 결과집합을 적절히 줄여줄 수 없다면, Join문으로 변환하여 코딩한다. 이 경우 다양한 Join 기법을 이용하여 Optimizer를 쉽게 통제 하기 쉽다.

l         Forms query시에 client에서 건마다 수행되는 post-query는 Network 및 전체 수행시간에 많은 부하를 미치게 된다. Post-query를 없애고, 조회 대상의 결과를 메인문장에 포함시켜 1회의 SQL로 수행시켜야 한다. => post-query는 속도 저하를 시키므로 될수 있으면 사용을 자제한다.

l         DB Link의 사용이 불가피한 경우 /*+ DRIVING_SITE(EMP) */ 등의 힌트를 사용하여 작업량을 줄이는 노력을 실시한다.

l         드라이빙 테이블 : query문에서 먼저 사용하는 table 즉 from 테이블명에서 제일 처음 쓰는 테이블명

l         row의 숫자를 줄여줄 수 있는 테이블을  드라이빙 테이블로 선정하여 먼저 처리 함으로서 전체 실행 시간을 줄여줌

l         Inline View의 경우 Nested Loop Join 대신에 Hash Join이 사용되도록 힌트를 사용한다.

l         Optimizer : sql의 실행계획을 수립, RDBMS의 핵심, RULE => RBO(Rule based optimization), choose(default로 선택), All_rows(전체처리율의 최적화), first_rows(최초결과가 나올때까지의 시간을 줄이기 위해 최적화), 항상 optimizer가 최선의 선택을 하는 것은 아니다. 따라서 Hint(사용자가 정보를 제공)를 통해서 정보를 주어야 한다.

Instance 레벨, session 레벨, 명령문레벨(hint)

l          RBO(rule based optimization)

l          CBO(cost based optimization) : 보다 현실적이고 지능적인 판단, 정확한 통계정보, Hint

/*+ Rule */를 제외하면 항상 CBO 호출.

Cardinality : 중요함.

l         부등호 중 조건이 들어간 것, ~보다 크고 ~보다 작다는 속도가 많이 걸림. 그러나 그냥 크다, 작다는 속도가 빠름.

 

 

자주 참조하는 딕셔너리 

세션과 관련된 정보

-------------------------------------------

V$SESSION : 세션에 대한 전반적인 정보를 보여준다

V$SESSSTAT : 세션의 현황에 대한 통계정보를 보여준다

V$SESSION_WAIT : 세션의 WAITING 통계정보를 보여준다

V$SESSION_EVENT : 세션의 현재 WATING EVENT를 보여준다

V$SESS_IO : 세션의 IO현황을 보여준다

V$STATNAME : SESSSTAT의 STATUS의 이름을 보여준다.

 

성능 관련 정보

--------------------------------------------

V$SYSTAT : 시스템 전반의 성능 통계 정보를 보여준다

V$SYSTEM_EVENT : 시스템의 WATING EVENT별 통계정보를 보여준다

V$LIBRARYCACHE : 라이브러리 캐쉬 사용 정보를 보여준다.

V$ROWCACHE : 데이터 딕셔너리의 사용정보를 보여준다

V$LATCH : LATCH에 대한 정보를 보여준다

V$LOCK : LOCK에 대한 정보를 보여준다

V$LOCKED_OBJECT : LOCK이 걸린 오브젝트에 대한 정보를 보여준다

V$SQLAREA : SQLAREA에 대한 정보를 보여준다

V$WAITSTAT : 시스템의 현재 Waiting현황을 보여준다

 

SQL관련

----------------------------------------------

V$SQL : Parse된 SQL문장을 보여줌

V$SQLTEXT : 라인별로 SQL문장을 보여줌

V$SQLTEXT_WITH_NEWLINES : NewLine을 포함하여 SQL문장을 보여줌

 

시스템 구성정보

----------------------------------------------

V$SGA : SGA 의 정보를 보여준다

V$PARAMETER : InitSID.ora 등에서 설정된 파라메터, 즉 데이터베이스의 구동되었을 때의 환경 파라메터 정보이다

V$CONTROLFILE : Control 파일에 대한 정보를 보여준다.

V$DATAFILE : 데이터 파일에 대한 정보를 보여준다.

V$LOG, V$LOGFILE : 리두 로그에 대한 정보를 보여준다.

 

USER

----------------------------------------------

DBA_USERS : 데이터베이스 USER에 대한 정보를 보여준다

 

권한

----------------------------------------------

DBA_ROLES : ROLE에 대한 정보를 보여준다.

DBA_TAB_PRIVS : 테이블에 대한 권한이 설정된 정보를 보여 준다

DBA_SYS_PRIVS : SYSTEM 권한이 설정된 정보를 보여준다

DBA_ROLE_PRIVS : ROLE에 대한 권한이 설정된 정보를 보여 준다.

DBA_COL_PRIVS : 컬럼 단위로 권한이 설정된 정보를 보여준다.

 

세그먼트&오브젝트

----------------------------------------------

DBA_SEGMENTS : 세그먼트(저장공간이 있는 오브젝트)에 대한 정보를 보여준다.

DBA_OBJECTS : 모든 오브젝트에 대한 정보를 보여준다.

 

테이블스페이스

----------------------------------------------

V$TABLESPACE : 테이블 스페이스에 대한 정보를 보여준다.

DBA_TABLESPACES : 테이블 스페이스에 대한 정보를 보여준다.

DBA_DATA_FILES : 테이블스페이스를 구성하고 있는 데이터 파일에 대한 정보를 보여준다.

DBA_FREE_SPACE : 아직 사용되지 않은 영역에 대한 정보를 보여준다.

DBA_EXTENTS : 할당된  EXTENT의 정보를 보여준다.

DBA_TS_QUOTAS : QUOTA가 설정된 정보를 보여준다

 

테이블

-----------------------------------------------

DBA_TABLES : 테이블에 대한 정보를 보여준다.

DBA_TAB_COLUMNS : 테이블을 구성하는 컬럼에 대한 정보를 보여준다

DBA_TAB_COMMENTS : 테이블의 설명에 대한 정보를 보여준다

DBA_PART_TABLES : 파티션 테이블에 대한 정보를 보여준다.

DBA_PART_KEY_COLUMNS : 파티션을 구성하는 기준 컬럼에 대한 정보를 보여준다

DBA_COL_COMMENTS : 컬럼에 대한 설명에 대한 정보를 보여 준다

 

인덱스

-----------------------------------------------

DBA_INDEXES : 인덱스에 대한 정보를 보여준다.

DBA_PART_INDEXES : 파티션된 인덱스에 대한 정보를 보여준다

DBA_IND_COLUMNS : 인덱스를 구성하는 컬럼에 대한 정보를 보여준다

 

CONSTRAINT

-----------------------------------------------

DBA_CONSTRAINTS : 테이블에 걸려있는 제약조건을 보여준다.

DBA_CONS_COLUMNS : 제약조건을 구성하는 컬럼에 대한 조건을 보여준다.

 

-----------------------------------------------

DBA_VIEWS : VIEW를 정의한 정보를 보여준다.

 

시노님

-----------------------------------------------

DBA_SYNONYMS : 시노님에 대한 정보를 보여준다.

 

시퀀스

-----------------------------------------------

DBA_SEQUENCES : 시퀀스에 대한 정보를 보여준다.

예제) select *
from DBA_SEQUENCES a
where a.sequence_name =
'XARK_TAX_INVOICES_ALL_S' ;

 

DB LINK

-----------------------------------------------

DBA_DB_LINKS : DB 링크에 대한 정의를 보여준다

 

트리거

-----------------------------------------------

DBA_TRIGGERS : 트리거에 대한 정의를 보여준다.

DBA_TRIGGER_COLS : 컬럼 단위로 작성된 트리거에 대한 정의를 보여준다.

 

ROLLBACK

-----------------------------------------------

DBA_ROLLBACK_SEGS : 롤백세그먼트에 대한 정보를 보여 준다.

 

FUNCTION, PROCEDURE, PACKAGE

-----------------------------------------------

DBA_SOURCE : FUNCTION, PROCEDURE,PACKAGE를 구성하는 PL/SQL 소스코드를 보여준다

 

 TKPROF : Trace시 그 결과가 어떤 파일에 쌓인다. 그런데 그건 기계어로 되어있다. Tkprof를 돌려서 기계어를 인간어로 변환시켜 준다.

 

 

 

 

TO_CHAR Date Format Specifiers

 

Format Model

Description

CC, SCC

Century (S prefixes BC dates with a minus sign)

YYYY, SYYYY

Year (S prefixes BC dates with a minus sign)

IYYY

Year based on ISO standard

YYY, YY, Y

Last three, two or one digits of the year

IYY, IY, I

Last three, two or one digits of the ISO year

Y,YYY

(Four Y's with comma) put a comma in the year (1,995)

YEAR, SYEAR

Year spelled out (S prefixes BC dates with a minus sign)

RR

Last two digits of year in another century (allows for year 2000)

BC, AD

BC or AD indicator

B.C., A.D.

BC or AD indicators with periods

Q

Numeric quarter of the year (1-4 with Jan-Mar=1)

MM

2 number month (Jan = 01)

RM

Roman numeral month

MONTH

Name of month spelled out (upper case - month is upper case)

MON

abbreviated name of month (upper case - month is upper case)

WW

Week of the year (1-53)

IW

Week of the year (1-52, 1-53) based on ISO standard

W

Week of month (1-5)

DDD

day of year (1-366) (Don't forget leap years)

DD

day of month (1-31)

D

day of week (1-7)

DAY

Name of day (upper case, day is upper case)

DY

Abbreviated name of day

J

Julian day (Number of days since January 1, 4712 BC)

AM,PM

Meridian indicator

A.M., P.M.

Meridian indicator with periods.

HH, HH12

Hour of day (0-12)

HH24

Use 24 hour clock for hours (1-24)

MI

Minute (0-59)

SS

Second (0-60)

SSSSS

(five S's) seconds past midnight. (0-86399)

None

Date must be in the format 'DD-MON-YY';

 

 

 

 

PL_SQL DEVELOPER 사용법

세미콜론으로 분리된 부분만 실행하고자 할 때 : tool -> preference -> sql window -> AutoSelect statement

-. Window -> save layout 하면 틀을 지정해놓은 데로 사용가능.

-. Pl/sql에서 스캔 방법

Tool -> find database objects 실행

찾고자 하는 table명칭을 ‘text to find’에 기록. Owner는 apps, name에 xomk%, object Types

-. 필터를 해도 원하는 내용이 나오지 않을 때 ‘메뉴 -> tool -> preference -> options -> use DBA Views if available’를 체크해야 필터의 내용이 정확하게 나온다.


출처 : http://blog.naver.com/zxr_6r/20040863595

반응형