Oracle 22強-PL/SQL匿名ブロック

6339 ワード

PL/SQL (Procedual Language SQL)
  • 標準SQL機能を拡張した構文(ブランチ、重複、変数など)
  • を提供
  • プリコンパイルメモリは、処理速度と効率を向上させる
  • .
  • モジュール化およびパッケージング機能
  • 標準文法がない
  • は各DBMSに依存する--私が使用しているDBMS構文によって異なり、
  • 匿名ブロック(Anonymous Block)、プログラム、機能、Tregger、Packageなど
  • 匿名ブロック--主に認証に使用され、
  • は保存されません.
  • 単純スクリプトで実行されるブロック(名前なし)
  • 格納不可
  • PL/SQLの基本構造
    (フォーマットを使用)
    DECLARE-CREATE、PROCEDURE、FUNCTIONが表示されると、それぞれのPL/SQLになります
    宣言変数、定数、およびカーソルの宣言
    BEGIN
    執行部;--問題解決のためのビジネスロジックSQL文
    [EXCEPTION-すべての例外を処理可能
    異常処理部品;
    END;
  • 例)キーボードを使用して部門番号を入力し、匿名ブロックを作成し、部門の住所、人数、平均給与を出力します.
      ACCEPT P_DEPT_NO PROMPT '부서코드 입력(10-110) : ' --P_DEPT_NO:변수(P:파라미터라는 뜻)
      DECLARE
        V_DEPT_NO HR.DEPT.DEPARTMENT_ID%TYPE := TO_NUMBER('&P_DEPT_NO'); 
        --&:참조하는 방식(포인터 안의 내용을 참조하라는 기호
                        ,실행할 때 &안에 있는 자료를 꺼내서 참조하라)
        V_CNT NUMBER:=0;--V_DEPT_NO:(V:변수라는 뜻)
        V_ASAL NUMBER:=0;
        V_ADDR VARCHAR2(200);
      BEGIN
        SELECT A.STREET_ADDRESS||' '||A.CITY||' '||A.STATE_PROVINCE --주소를 얻기위한 SELECT문
          INTO V_ADDR --주소를 할당
          FROM HR.LOCATIONS A, HR.DEPT B
         WHERE A.LOCATION_ID=B.LOCATION_ID
           AND B.DEPARTMENT_ID=V_DEPT_NO;
           
        SELECT COUNT(EMPLOYEE_ID), --사원의 수
               ROUND(AVG(SALARY)) --그 부서의 평균급여
          INTO V_CNT,V_ASAL     --두 개의 변수에 각각 할당해줌
          FROM HR.EMP
         WHERE DEPARTMENT_ID=V_DEPT_NO; 
         
        DBMS_OUTPUT.PUT_LINE('부서번호 : '||V_DEPT_NO); --SYSTEM.OUT.PRINTLN과 같음
        DBMS_OUTPUT.PUT_LINE('주소 : '||V_ADDR);
        DBMS_OUTPUT.PUT_LINE('인원수 : '||V_CNT);
        DBMS_OUTPUT.PUT_LINE('평균급여 : '||V_ASAL);
      END;  
    TO NUMBER('&P DEPT NO')-文字列タイプがNUMBERタイプ
    ":=":Javaの割り当て演算子と同じ
    V_DEPT_NO HR.DEPT.DEPARTMENT_ID%TYPE := TO_NUMBER('&P_DEPT_NO');
    -> HR.宣言変数のタイプ(DEPT.DEPARTMENT ID(参照タイプ)など)
    ゾーン変数は使用前に初期化する必要があります.
    V_CNT NUMBER:=0;
    ->NUMBERタイプを初期化する必要があります(初期化されていない場合はNULL値)
    初期化しないとSCRIPTRUNNERは往復移動のみ-停止後0世代がNUMBERに加入
    SELECT文はPL/SQLのBEGINブロックにおいてSELECT~INTOとして用いられる
    SELECTが2つのカラムを使用する場合、INTOも2つの変数を割り当てる必要があります.
    宣言にはSELECT~INTO文は使用されません.
    BEGINブロックでのみSELECT~INTO節、その他の部分ではSELECT FROM節
    SELECT位置の選択
    INTO変数への割当て
    DBMS_OUTPUT.PUT LINE(「部門番号:」|V DEPT NO);--JavaでPRINTLNと同じ役割
    スクリプト出力ウィンドウに結果は表示されず、DBMS出力ウィンドウに結果が表示されます
    結果をクリアできません.消しゴムツールをクリックして直接クリアしてください.
    SCALR変数:一瞬に1つの値しか入力できない変数
    同じタイプの複数の変数を同時に格納できる変数:配列
    参照タイプの行参照タイプはJavaのArrayListに類似しており、C言語の構造と同じである
    構造体:異なるタイプのデータ->データを一度に格納できますが、操作データの動作はありません.
    (Javaの)class:データの格納と操作が可能
    1)変数と定数
  • SCALAR変数、REFERENCE変数を提供
    (宣言形式)
    変数(定数)名[CONSTANT]データ型|参照タイプ[:=初期値];定数の場合はCONSTANT、変数の場合は
  • を省略する
  • データ型
    を選択します.標準的なクラウドコンピューティングで使用されるデータ型
    .PLS INTEGER,BINARY INTEGER:4 BYTE整数(-24748-3414748647)
    .BOOLEANタイプ(true、false、null)
  • 参照タイプ
    .列参照タイプ:テーブル名.列名%TYPE
    .行参照タイプ:テーブル名%ROWTYPE--javaのArrayListと似ており、同じ構造の
  • 使用例)部門コードを生成し、その部門の従業員の数をカウントします.
    匿名のブロックを作成し、従業員番号、従業員名、入社日、職責コード、給与を印刷します.
      DECLARE
        V_EMP_ID HR.EMP.EMPLOYEE_ID%TYPE;
        V_ENAME HR.EMP.EMP_NAME%TYPE;
        V_JOB HR.EMP.JOB_ID%TYPE;
        V_SAL HR.EMP.SALARY%TYPE;
        V_DEPT_ID HR.DEPT.DEPARTMENT_ID%TYPE;
      BEGIN
        V_DEPT_ID:=TRUNC(DBMS_RANDOM.VALUE(10,110),-1); 
        --난수발생 VALUE(하한값,상한값) : 하한값~상한값 사이의 정수형 난수발생
        SELECT EMPLOYEE_ID,EMP_NAME,JOB_ID,SALARY
          INTO V_EMP_ID,V_ENAME,V_JOB,V_SAL
          FROM HR.EMP
         WHERE DEPARTMENT_ID = V_DEPT_ID 
           AND ROWNUM=1;
           
         DBMS_OUTPUT.PUT_LINE('사원번호 : '||V_EMP_ID);   
         DBMS_OUTPUT.PUT_LINE('사원명 : '||V_ENAME);
         DBMS_OUTPUT.PUT_LINE('직책 : '||V_JOB);
         DBMS_OUTPUT.PUT_LINE('급여 : '||V_SAL);
      END;
    最大
      DECLARE
        V_EMP_ID HR.EMP.EMPLOYEE_ID%TYPE;
        V_ENAME HR.EMP.EMP_NAME%TYPE;
        V_JOB HR.EMP.JOB_ID%TYPE;
        V_SAL HR.EMP.SALARY%TYPE;
        V_DEPT_ID HR.DEPT.DEPARTMENT_ID%TYPE;
      BEGIN
        V_DEPT_ID:=TRUNC(DBMS_RANDOM.VALUE(10,110),-1); 
      SELECT A.EMPLOYEE_ID, A.EMP_NAME,A.JOB_ID,A.SALARY 
        INTO V_EMP_ID,V_ENAME,V_JOB,V_SAL
        FROM (SELECT EMPLOYEE_ID,EMP_NAME,JOB_ID,SALARY
                FROM HR.EMP
               WHERE DEPARTMENT_ID = V_DEPT_ID
               ORDER BY 4 DESC) A
       WHERE ROWNUM=1;
           
         DBMS_OUTPUT.PUT_LINE('사원번호 : '||V_EMP_ID);   
         DBMS_OUTPUT.PUT_LINE('사원명 : '||V_ENAME);
         DBMS_OUTPUT.PUT_LINE('부서코드 : '||V_DEPT_ID);
         DBMS_OUTPUT.PUT_LINE('직책 : '||V_JOB);
         DBMS_OUTPUT.PUT_LINE('급여 : '||V_SAL);
      END;
    
     COMMIT;
    使用例)2005年7月29日に「h 001」メンバーが2つの「P 2020,00012」製品を購入した場合、この情報をCARTテーブルに保存します.
    --行うべき1.2005年7月29日の売上高を確認する
    データ数が1の場合はCOUNTで購入->
    0人->未購入
     DECLARE
        V_CNT NUMBER:=0; --V_CNT: 레코드 수(2005년7월29일 매출이 있는지 확인하는 변수) 
        V_CART_NO CART.CART_NO%TYPE;
     BEGIN
        SELECT COUNT(*) INTO V_CNT --2005년7월29일 매출 행이 존재하는지 확인
          FROM CART
         WHERE CART_NO LIKE '20050729%;';
         
         IF V_CNT=0 THEN --매출이 없다(0이다)
            V_CART_NO:='2005072900001'; --카트번호 부여         
         ELSE --매출이 있다. V_CNT값이 0이 아니다(이미 데이터가 존재한다)
            SELECT CART_NO INTO V_CART_NO --1번이 부여됨
              FROM CART
             WHERE CART_MEMBER='h001' --이 회원이
               AND SUBSTR(CART_NO,1,8)='20050729' --이 날
               AND CART_PROD='P202000012';
               --이 상품을 구매한 이력이 있는지 없는지 판별 -있으면 수를 추가, 없으면 INSERT
         END IF;      --여기까지 V_CART_NO가 NULL인 경우, NULL이 아닌 경우, V_CNT가 0인 경우
         IF V_CART_NO IS NULL AND V_CNT !=0 THEN  --안샀으면 NULL
            INSERT INTO CART --V_CART_NO가 NULL인 경우 : 매출은 있지만 그 회원이 그 날 그 제품을 사지는 않음
              SELECT 'h001',MAX(CART_NO)+1,'P202000012',2 --구매한적없음, 카트번호중 제일 큰 번호에 다음번호
                FROM CART
               WHERE CART_NO LIKE '20050729%';
         ELSIF V_CART_NO IS NOT NULL AND V_CNT !=0 THEN  --V_CART_NO가 NULL이 아닌 경우, 사간 경우     
              UPDATE CART
                 SET CART_QTY=CART_QTY+2 --그 회원이 이미 그 물건을 샀기 때문에 CART_QTY에 숫자만 2개 더해줌
               WHERE CART_MEMBER='h001'
                 AND SUBSTR(CART_NO,1,8)='20050729'
                 AND CART_PROD='P202000012';
         ELSIF V_CART_NO IS NOT NULL AND V_CNT =0 THEN --아무도 안 사간 경우 : 신규로 구매를 등록
            INSERT INTO CART
              VALUES('h001',V_CART_NO,'P202000012',2);  
         END IF;     
     END;