PL / SQL 기초 문법

튜 토리 얼 자료:http://www.w3ii.com/zh-CN/plsql/plsql_basic_syntax.html
다음 예 는 Oracle 을 설치 할 때 시스템 을 기반 으로 만 든 orcl 데이터베이스 emp 표 입 니 다.
Hello World
    set serveroutput on --       
    -- pl/sql  
    declare
       --     (    ,    ,    )
    begin --     
       ....    (DML  )
       dbms_output.put_line('Hello World'); --   Hello World
    exception
       --       
    end; --     
    / --                , SQL Developer   ,   PL/SQL Developer    ,set serveroutput on    。   
 *       insert/update/delete  ,SQL Developer     commit, PL/SQL Developer    (        )

변수 와 상수
  • 상용 변수 유형 char,varchar2,date,number,boolean,long 예 를 들 어
  •     varl      char(15);
        pi constant number := 3.141592654;
        married   boolean := true;
        psal      number(7,2);
        my_name   emp.ename%type;
        emp_rec   emp%rowtype;
        
        char(15):         15   。
        constant :     。
        boolean := true :      true。
        number(p,s): precision    ,          ,     ,   38  ,     1~38   。  
                         scale     ,             。    -84 127,        。
                        scale  ,    0,         。
        emp.ename%type:     emp ename  ,ename   my_name    。
        emp%rowtype:        ,               ,           。  
                     :emp_rec.ename(   ename    ),emp_rec.xxx(    )  
                              :emp_rec.ename := 'gordon'
    
         :  
        declare
             --            
             --pename   varchar2(20);
             --psal    number; p,s       p,s     
             pename emp.ename%type;
             psal   emp.sal%type;
        begin
            --   7839      ,    into       pename,psal
            select ename,sal into pename,psal from emp where empno = 7839;
            --   
            dbms_output.put_line(pename||'    '||psal);
        end;
        /
    
         :
        declare
            --        :    
            emp_rec emp%rowtype;
        begin
            select * into emp_rec from emp where empno = 7839;
            dbms_output.put_line(emp_rec.ename||'    '||emp_rec.sal);
        end;
        /
    
    

    조건문
  • 세 가지 방식:
  • IF    THEN   1;
          2;
    END IF;
    
    IF    THEN   1;
    ELSE   2;
    END IF;
    
    IF    THEN   1;
    ELSIF    THEN   2; --       ELSIF   ,  ELSEIF
    ELSE   3;
    END IF;
    

    예시:
    --       
    accept nums prompt '       ';
    -- nums :    ,            
    declare
       --            
       --     (          ),&          
       pnum number := &nums;--          pnum    
    begin
       if pnum = 0 then
         dbms_output.put_line('     0');
       elsif pnum = 1 then
         dbms_output.put_line('     1');
       elsif pnum = 2 then
         dbms_output.put_line('     2');
       else
         dbms_output.put_line('       :' || pnum);
       end if;
    end;  
    

    순환 문
  • 세 가지 방식:
  • WHILE total <= 20000 --           
    LOOP
    ....    
    total := total + salary;
    END LOOP;
    
    LOOP
    EXIT when   ;--           ,      
    ....    
    END LOOP;
    
    FOR I IN 1 .. 3 
    -- 1..3 :       3     I = 1,I = 2,I = 3。  :5..100(   5 100     )
    LOOP
    ....    
    END LOOP;
    

    예시:
    /*
       1 - 10
    */
    declare
      pnum number := 1;
    begin
        loop
          exit when pnum > 10;
          dbms_output.put_line(pnum);
          pnum := pnum + 1;
        end loop;
    end;
    

    Cursor (커서) = = ResultSet (결과 집합)
  • 커서 문법 CURSOR [( , ....)] IS SELECT
  • 되 돌아 오 는 여러 줄 의 데 이 터 를 저장 하 는 데 사 용 됩 니 다 cursor cs is select ename from emp;
  • 커서 열기:   open  cs;(커서 를 열 어 조 회 를 실행 합 니 다)
  • 한 줄 의 커서 값 을 가 져 옵 니 다:  fetch cs into pename;(한 줄 의 값 을 가 져 와 pename 변수 에 할당 합 니 다)
  • 커서 닫 기:   close  cs;(커서 를 닫 고 자원 방출)
  • 커서 속성
  • % isopen: 활성화 여부
  • % rowcount: 유효한 줄 수 입 니 다. 예 를 들 어 커서 에 100 개의 기록 이 있 지만 10 개의 기록 만 되 돌려 줍 니 다. 그러면 rowcount 는 10 입 니 다.
  • % notfound: 찾 을 수 없 음
  • % found: 찾 았 습 니 다
  • Oracle 은 세 션 마다 한 번 에 300 개의 커서 만 열 수 있 습 니 다.물론 이 기본 값 을 수정 하여 관리자 로 Oracle 에 들 어가 alter 를 실행 할 수 있 습 니 다.  system  set  open_cursors=400;

  • cursor 커서 와 ResultSet 커서 의 차이 점: ResultSet 커서 의 초기 위 치 는 첫 번 째 줄 데이터 의 이전 위치 이 고 cursor 커서 의 초기 위 치 는 첫 번 째 줄 데이터 예제 입 니 다.
  •     /*
              1000   800   400
        */
        declare
            --              
            cursor cemp is select empno, empjob from emp;
            --        
            pempno emp.empno%type;
            pjob   emp.empjob%type;
        begin
           open cemp;--     
            loop
              --           pempno,pjob
              fetch cemp into pempno, pjob;
              exit when cemp%notfound; --            
              --   
              if pjob = 'PRESIDENT' then
                update emp set sal = sal + 1000 where empno = pempno;
              elsif pjob = 'MANAGER' then
                update emp set sal = sal + 800 where empno = pempno;
              else
                update emp set sal = sal + 400 where empno = pempno;
              end if;
            end loop;
            close cemp;--     
        end;
    
            cursor:
        /*
                   
        */
        declare
            --       dno,  deptno = dno         
            cursor cemp(dno number) is select ename from emp where deptno = dno;
            pename emp.ename%type;
        begin
            open cemp(10);--  Java   ,        ,      .    10   
            loop
              fetch cemp into pename;
              exit when cemp%notfound;
              dbms_output.put_line(pename);
            end loop;
            close cemp;  
        end;
    

    예외 처리
  • 시스템 정의 이상
  • NO_data_found    데이터 가 없습니다
  • Too_many_rows    select... into 문장 일치 다 중 줄 (다 중 줄 데이터 할당 단일 변수)
  •         declare
            pename emp.ename%type;
            begin
            select ename into pename from emp;
            end;
    
    + Zero\_Divide       ,  1/0
    + Value\_error           
    + Timeout\_on_resource            
    
            /*
                
            */
            declare
               pnum number;
            begin
               pnum := 1/0;
            exception
               --    
               when zero_divide then dbms_output.put_line('1:0      ');
                                     dbms_output.put_line('2:0      ');
               --                              
               when value_error then dbms_output.put_line('       ');
               --      others :           
               when others then dbms_output.put_line('    ');     
               --  PL/SQL            ,           ,                                       
            end;
    
  • 사용자 정의 이상
  • /*
         
      50        (      50   )
    */
    declare
      cursor cemp is select ename from emp where deptno = 50;
      pename emp.ename%type;
      --      
      no_emp_found exception;
    begin
      open cemp;
         --      
         fetch cemp into pename;
         if cemp%notfound then
           --        ,    raise
           raise no_emp_found;
         end if;
      --         close cemp     ,
      --   Oracle   Process monitor   java                 
      close cemp;
    exception
      when no_emp_found then dbms_output.put_line('     ');
      when others then dbms_output.put_line('    ');
    end;
    

    실례
  • 실례 1
  •  /*
               , :
    total    1980     1981     1982     1987
       15      1       10        2        2
     */
    declare
       -- to\_char:            ,                 
       cursor ctemp is select to\_char(hiredate, 'yyyy') from emp;
       pyear   varchar2(4);
       pcount0 number := 0;
       pcount1 number := 0;
       pcount2 number := 0;
       pcount7 number := 0;
    begin
       open ctemp;
       loop
          fetch ctemp into pyear;
          exit when ctemp%notfound;
          if pyear = '1980' then
             pcount0 := pcount0 + 1;
          elsif pyear = '1981' then
             pcount1 := pcount1 + 1;
          elsif pyear = '1982' then
             pcount2 := pcount2 + 2;
          else
             pcount7 := pcount7 + 1;
          end if;
       end loop;
       close ctemp;
       dbms\_output.put_line('total:' ||
                            (pcount0 + pcount1 + pcount2 + pcount7) ||
                            '  1980:' || pcount0 || '  1981:' || pcount1 ||
                            '  1982:' || pcount2 || '  1987:' || pcount7);
    end;
    
  • 실례 2
  • /*
          。          10%,         5  ,
                       
    */
    declare
      -- order by      ,         
      cursor cemp is select empno,sal from emp order by sal;
      pempno emp.empno%type;
      psal emp.sal%type;
      pcount number := 0;
      ptotal number;
    begin
      --         
      select sum(sal) into ptotal from emp;
      dbms_output.put_line('      :'||ptotal);
      open cemp;
             loop
                exit when ptotal > 50000;--      5000   
                fetch cemp into pempno,psal;
                exit when cemp%notfound;--  cemp      
                --    
                update emp set sal = sal * 1.1 where empno = pempno;
                --       
                pcount := pcount + 1;
                --        
                ptotal := ptotal + psal \* 0.1;
             end loop;
          close cemp;
          commit;
          dbms_output.put_line('      :'||pcount||'      : '||ptotal);
    end;
      :        ,                。
        :        ,                      ,
                      10%               。          。
        :                  , 3              。
    
  • 실례 3
  •        (3000   ,3000 ~ 6000,6000  ),           ,
              (          ),    :
          <3000    3000~6000    >6000        
    10        2         1            0      8750
    20        3         2            0      10875
    30        6         0            0      9400
    40        0         0            0      0
    --             
    drop table msg;
    create table msg(deptId number,count3 number,count6 number,count9 number,saltotal number);
    declare
       --                       
       cursor cdept is select deptno from dept;
       pdeptno   dept.deptno%type;
       cursor csal(tno number) is select sal from emp where deptno = tno;
       psal      emp.sal%type;
       pcount3   number;
       pcount6   number;
       pcount9   number;
       ptotalSal number;
    begin
       open cdept;
       loop
              fetch cdept into pdeptno;
              exit when cdept%notfound;
              pcount3   := 0;
              pcount6   := 0;
              pcount9   := 0;
              ptotalSal := 0;
              
              open csal(pdeptno);
              loop
                 fetch csal into psal;
                 exit when csal%notfound;
                 if psal < 3000 then
                    pcount3 := pcount3 + 1;
                 elsif psal > 3000 and psal < 6000 then
                    pcount6 := pcount6 + 1;
                 elsif psal > 6000 then
                    pcount9 := pcount9 + 1;
                 else
                    dbms_output.put_line('       ');
                 end if;
                 ptotalSal := ptotalSal + psal;
                 --       pdeptno            
                 -- select sum(sal) into ptotalSal from emp where deptno = pdeptno;
              end loop;
              close csal;
              --            ,nvl(p1,p2):        ,  p1 null   p2,    p1
              insert into msg values(pdeptno,pcount3,pcount6,pcount9,ptotalSal);
              dbms_output.put_line(pdeptno || '  ' || '  3k: ' || pcount3 ||
                                   '  3-6k: ' || pcount6 || '  >6k: ' || pcount9 ||
                                   '      : ' || ptotalSal);
          end loop;
          close cdept;
          commit;
    end;
    

    좋은 웹페이지 즐겨찾기