11. ORACLE :: PL/SQL, PROCEDURE, FUNCTION,TRIGGER, CURSOR 정리

2024. 6. 13. 17:25·Oracle DataBase

1. PL/SQL

Procedural Language extension to SQL의 약자

오라클 자체 내장된 절차적 언어

SQL단점을 보완하여 문장 내에서 변수 정의, 조건 처리, 반복 처리 등을 지원함

  • 대입연산 기호 (:=) 바뀌므로 주의
  • 레코드 타입 변수: 다수의 자료형을 저장할 수 있는 일종의 묶음 자료형
  • 🚨 END; 아래 (/)슬래시를 입력해줘야 구문 전체를 실행시킬 수 있다.

사전세팅 :: 출력용 환경변수 켜기

  • 프로시저를 사용하여 출력하는 내용을 화면에 띄워주는 환경변수를 ON처리 해줘야 변수를 볼 수 있음
    • SET SERVEROUTPUT ON; → OFF가 디폴트
    • 접속할때마다 세팅해줘야함
SET SERVEROUTPUT ON;
begin 
    dbms_output.put_line('안녕 PL/SQL'); -- on으로 해줘야 뜸(접속마다 설정)
end;

구조

구조 시작 내용
DECLARE SECTION
선언부
DECLARE 변수나 상수를 선언하는 부분
- 변수명 자료형(크기)
EXECUTABLE SECTION
실행부
BEGIN 로직 기술부, ; 삽입 필요
(SELECT : 반드시 특정 변수에 필요 데이터를 저장하고 활용해야 한다.(INTO 활용))
- 레퍼런스 변수, rowtype변수, 테이블 타입 변수, 레코드 타입 변수 이용가능
- 선택문, 반복문 사용가능
EXCEPTION SECTION
예외처리부
EXCEPTION 예외 발생시 해결 로직 작성
- 실행부에 포함된다
- WHEN ~ THEN ~
  END 실행부 끝나면 명시 필요

 

DECLARE 변수 활용하기

변수는 DECLARE 부분에 변수명 자료형 형식으로 선언

변수 종류

  • 기본 자료형: 오라클이 제공하는 타입: 문자, 숫자, 날짜의 형식(1개)
    • 기본자료형 예시
DECLARE
	V_EMPNO VARCHAR2(20);
	V_EMPNAME VARCHAR2(10);
	V_AGE NUMBER;
	V_DATE DATE;
BEGIN
	-- 변수에 값 대입: 대입연산자(:=) 이용
	V_EMPNO := '200';
	V_EMPNAME := 'JOHN';
	V_AGE := 29;
	V_DATE := TO_DATE('24/02/13','YY/MM/DD');
    DBMS_OUTPUT.PUT_LINE(V_EMPNO);
		DBMS_OUTPUT.PUT_LINE(V_EMPNAME);
		DBMS_OUTPUT.PUT_LINE(V_AGE);
		DBMS_OUTPUT.PUT_LINE(V_DATE);
    
    -- SELECT : 반드시 특정 변수에 필요 데이터를 저장하고 활용해야 한다.(INTO 활용)
    SELECT EMP_NO, EMP_NAME
    INTO V_EMPNO, V_EMPNAME
    FROM EMPLOYEE WHERE EMP_ID = 200;
    DBMS_OUTPUT.PUT_LINE(V_EMPNO);
		DBMS_OUTPUT.PUT_LINE(V_EMPNAME);
END;
/
    • 기본형은 계속 맞춰서 형변환을 해줘야하는데 참조 자료형은 테이블의 데이터 타입이 바뀌면 알아서 같이 바뀌기 때문에 그보다 유동적 대처가 가능하다.참조 자료형: 테이블 컬럼에 선언되어있는 타입을 참조하는 것(1개)
DECLARE
    V_EMPID EMPLOYEE.EMP_ID%TYPE; -- EMPLOYEE 테이블의 emp_id의 타입을 가져온다는 의미
    V_SALARY EMPLOYEE.SALARY%TYPE;
BEGIN
    V_EMPID := 'CH';
    V_SALARY := 7000;
    DBMS_OUTPUT.PUT_LINE(V_EMPID || ' ' || V_SALARY);
    
    SELECT EMP_ID, SALARY
    INTO V_EMPID, V_SALARY
    FROM EMPLOYEE
    WHERE EMP_ID = '&사원번호'; -- &사용시 입력창이 뜬다.
    
    DBMS_OUTPUT.PUT_LINE(V_EMPID || ' ' || V_SALARY);
END;
/

ROWTYPE(여러개)

  • 테이블에 선언된 전체 컬럼 타입을 가져와 적용하는 것(참조)
    • 컬럼명으로 가져올 수 있다.
  • 즉, 1개 row 저장 가능

 

DECLARE
    V_EMP EMPLOYEE%ROWTYPE;
    V_DEPT DEPARTMENT%ROWTYPE;
BEGIN
    SELECT *
    INTO V_EMP
    FROM EMPLOYEE
    WHERE EMP_ID = '&EMP_ID';
    --ROW타입에 저장된 데이터는 컬럼명으로 가져올 수 있다.
    
    DBMS_OUTPUT.PUT_LINE(V_EMP.EMP_ID || V_EMP.EMP_NAME || V_EMP.EMP_NO);
    
    SELECT * --DEPT_ID AS DEPTID, DEPT_TITLE AS DEPTTITLE
    INTO V_DEPT
    FROM DEPARTMENT
    WHERE DEPT_ID = '&부서코드';
    DBMS_OUTPUT.PUT_LINE(V_DEPT.DEPT_ID || V_DEPT.DEPT_TITLE || V_DEPT.LOCATION_ID);
END;
/

 


아래는 타입을 생성해서 선언하는 변수

TABLE(1개)

  • 자바의 배열과 유사한 자료형
  • 한개 타입의 여러 값을 저장
  • 사용시 인덱스 번호로 접근
-- table type
DECLARE
    TYPE EMPNAME_TABLE IS TABLE OF EMPLOYEE.EMP_NAME%TYPE
    INDEX BY BINARY_INTEGER;
    
    EMPNAMES EMPNAME_TABLE; --하나의 자료형이므로 바로 삽입 가능
    I BINARY_INTEGER := 1;
BEGIN
    EMPNAMES(1) := 'SAM';
    EMPNAMES(2) := 'JOHN';
    EMPNAMES(3) := 'STEVE';
    EMPNAMES(4) := 'SOPIA';
    EMPNAMES(5) := 'JULIA';
    
    --DBMS_OUTPUT.PUT_LINE(EMPNAMES(1) || EMPNAMES(2) || EMPNAMES(3) || EMPNAMES(4) || EMPNAMES(5));
    --반복문 사용이 더 용이한 경우
    FOR K IN 1..5 LOOP
        DBMS_OUTPUT.PUT_LINE(EMPNAMES(K));
    END LOOP;
    
    --이름들을 가져와서 저장해볼까요
    FOR E IN(SELECT * FROM EMPLOYEE) LOOP
        EMPNAMES(I) := E.EMP_NAME;
        I := I+1;
    END LOOP;
    
    FOR K IN 1..I-1 LOOP --I가 1부터 시작이기 때문에 I-1까지 루프
        DBMS_OUTPUT.PUT_LINE(EMPNAMES(K));
    END LOOP;
END;
/
  • RECORD(여러개)
    • 자바의 클래스와 유사
    • 다수 타입의 여러 값을 저장
    • 변수 명으로 접근해서 사용
DECLARE
    TYPE MYRECORD IS RECORD(
        EMPID EMPLOYEE.EMP_ID%TYPE,
        EMNAME EMPLOYEE.EMP_NAME%TYPE,
        DEPTITLE DEPARTMENT.DEPT_TITLE%TYPE,
        JOBNAME JOB.JOB_NAME%TYPE
);

MYDATA MYRECORD;
BEGIN
    SELECT EMP_ID, EMP_NAME, DEPT_TITLE, JOB_NAME
    INTO MYDATA
    FROM EMPLOYEE
        LEFT JOIN DEPARTMENT ON DEPT_CODE = DEPT_ID
            JOIN JOB USING(JOB_CODE)
        WHERE EMP_NAME = '&이름';
        
    DBMS_OUTPUT.PUT_LINE(MYDATA.EMPID || MYDATA.EMNAME || MYDATA.JOBNAME);
    
END;
/

사용방법

(1) 익명 블록 이용(기본적인 방법)

많이 안씀

[DECLARE
	필요한 변수 선언]
BEGIN
	실행할 로직 작성;
END

(2) OBJECT(PROCEDURE, FUNCTION, TRIGGER) 이용

아래 참조

조건문 종류

(1) IF

@ 작성방법
IF 조건문
	THEN true일때 실행할 내용
END IF;

@ 예시
-- 월급 200이상인 사원 이름 검색
DECLARE
    V_SALARY EMPLOYEE.SALARY%TYPE;
BEGIN
    SELECT SALARY
    INTO V_SALARY
    FROM EMPLOYEE
    WHERE EMP_NAME = '%사원명';
    
    IF V_SALARY > 2000000
        THEN --DBMS_OUTPUT.PUT_LINE('우와 200만원 보다 많이 받는다!!')
            INSERT INTO HISTORY VALUES(V_SALARY,SYSDATE); -- 저장까지해보기.
            COMMIT; -- 저장을 했다면 커밋까지 써줘야한다.
    END IF;
END;
/

CREATE TABLE HISTORY(
    SALARY NUMBER,
    TODAY DATE
);

(2) IF ~ ELSE

@ 작성방법
IF 조건문
	THEN 실행문
	ELSE 실행문
END IF;

@ 예시
--월급 400이상인 사원 이름 검색
DECLARE
    V_SALARY EMPLOYEE.SALARY%TYPE;
BEGIN
    SELECT SALARY
    INTO V_SALARY
    FROM EMPLOYEE
    WHERE EMP_NAME = '&이름';
    
    IF V_SALARY > 4000000
        THEN DBMS_OUTPUT.PUT_LINE('WOW');
    ELSE DBMS_OUTPUT.PUT_LINE('GOGO');
    END IF;
END;
/

(3) IF ~ ELSIF ~ ELSE

조건이 많을 때 사용

@ 작성방법
IF 조건문
	THEN 실행문;
ELSIF 실행문
	THEN 실행문;
	.
	.
ELSE 실행문;
END IF;

@ 예시
-- JOB_TITLE출력 로직
DECLARE
    V_EMP_ID EMPLOYEE.EMP_ID%TYPE;
    V_JOB_CODE EMPLOYEE.JOB_CODE%TYPE;
    MSG VARCHAR2(10);
BEGIN
    SELECT EMP_ID, JOB_CODE
    INTO V_EMP_ID, V_JOB_CODE
    FROM EMPLOYEE
    WHERE EMP_ID = '&EMP_ID';
    
    IF V_JOB_CODE = 'J1'
        THEN MSG := 'CEO';
    ELSIF V_JOB_CODE IN ('J2', 'J3', 'J4')
        THEN MSG := '간부';
    ELSIF V_JOB_CODE IN ('J5', 'J6')
        THEN MSG := '사원';
    ELSE MSG := '인턴';
    END IF;
    DBMS_OUTPUT.PUT_LINE(MSG);
END;
/

(4) CASE문

이미 이전에 작성법은 함

DECLARE
    NUM NUMBER;
BEGIN
    NUM := '&NUM';
    CASE
        WHEN NUM > 10 THEN DBMS_OUTPUT.PUT_LINE(Num || '10초과');
        WHEN NUM > 5 THEN DBMS_OUTPUT.PUT_LINE(Num || '5초과');
        ELSE DBMS_OUTPUT.PUT_LINE(Num || '5이하값 입니다');
    END CASE;
END;
/

반복문

LOOP예약어만 이용해서 사용가능

반복문안에 조건을 입력하지 않으면 무한루프가 되므로 조심할 것

(1) 기본 반복문

-- 1~ 100까지 출력
DECLARE
    NUM NUMBER := 1;
    RNDNUM NUMBER;
BEGIN 
    LOOP
        DBMS_OUTPUT.PUT_LINE(NUM);
        IF NUM = 100
            THEN EXIT;
        END IF;        
        NUM := NUM + 1;
    END LOOP;
END;
/
  • 활용 예시
-- 무작위 데이터 100개 게시글 저장하기
CREATE TABLE FK_BOARD2(
    BOARD_NO NUMBER PRIMARY KEY,
    BOARD_TITLE VARCHAR2(200),
    BOARD_DATE DATE
);

CREATE SEQUENCE SEQ_BOARDNO;
DECLARE
    NUM NUMBER := 1;
    RNDNUM NUMBER;
BEGIN 
    LOOP
        DBMS_OUTPUT.PUT_LINE(NUM);
        RNDNUM := FLOOR(DBMS_RANDOM.VALUE(1,200));
        INSERT INTO FK_BOARD2 VALUES(SEQ_BOARDNO.NEXTVAL, 'TEST TITLE' || RNDNUM, SYSDATE);
        IF NUM = 100
            THEN EXIT;
        END IF;        
        NUM := NUM + 1;
    END LOOP;
END;
/

SELECT * FROM FK_BOARD2;

(2) while 반복문

@ 작성법
WHILE
WHILE 조건문 LOOP
실행구문
END LOOP;

-- 1~10까지 반복 출력
DECLARE
    NUM NUMBER := 1;
BEGIN
    WHILE NUM <= 10 LOOP
        DBMS_OUTPUT.PUT_LINE(NUM);
        NUM := NUM +1;
    END LOOP;
END;
/

(3) 기본 for문

@ 작성법
FOR 변수 IN 범위(시작..끝)LOOP -- 점 두개
		실행구문
END LOOP;

-- 기본 for
BEGIN
    FOR I IN 1..5 LOOP
        DBMS_OUTPUT.PUT_LINE(I);
    END LOOP;
END;
/

(4) select문으로 for문

조건별 분기넣어서 저장 또는 삭제 등으로 연결 가능

@ 작성법
FOR 변수 IN (SELECT문) LOOP
	실행구문
END LOOP;

-- select문으로 for실행해보기: 
BEGIN
    FOR E IN (SELECT * FROM EMPLOYEE) LOOP
        DBMS_OUTPUT.PUT_LINE(E.EMP_NAME || E.SALARY || E.BONUS || E.EMAIL);
        IF E.SALARY > 3500000
            THEN INSERT INTO HIGH_SAL VALUES(E.EMP_ID, E.SALARY, E.HIRE_DATE);
        ELSE INSERT INTO LOW_SAL VALUES(E.EMP_ID, E.SALARY, E.HIRE_DATE);
        END IF;
    END LOOP;
    COMMIT;
END;
/

SELECT * FROM HIGH_SAL;
SELECT * FROM LOW_SAL;
반응형

2. PROCEDURE & FUNCTION

PL/SQL문을 저장해서 쓸 수 있게 해주는 구문으로 간단히 호출해서 실행 결과를 얻을 수 있음

1) PROCEDURE

하나의 객체이기 때문에 create 구문을 사용한다.

@ 생성 방법
CREATE [OR REPLACE] PROCEDURE NAME
IS
[필요한 변수 선언]
BEGIN
	실행할 구문 작성 -> 저장되는 구문
END;
/

@ 실행방법
exec 프로시저명;

또한, 매개변수를 넣어서 생성할 수도 있다. → 유동적으로 돌아가기 위함

자바의 return과 비슷하지만, 받고 주는 것이 모두 매개변수로 이뤄진다는 차이가 있다.

매개변수 있는 :: IN/OUT procedure

(1) IN 매개변수

필요 데이터를 외부에서 받는 매개변수 : 일반적인 매개변수

  • 외부 변수는 오라클에서 전역변수 타입인 VAR 를 활용
    • var test varchar2(20);
create or replace procedure pro_select_emp(v_emp in employee.emp_id%type)
is 
    name varchar2(20);
begin
    select emp_name
    into name
    from employee
    where emp_id = v_emp;
    dbms_output.put_line(name);
end;
/

set serveroutput on;
exec pro_select_emp('200');

(2) OUT 매개변수

호출한 곳에서 지정한 변수에 프로시저 실행 결과를 저장받는 매개변수

--이름을 전달받으면 이름을 출력하는 프로시저
create or replace procedure pro_select_emp2(v_emp in employee.emp_id%type,
    v_name out employee.emp_name%type)
is 
    name varchar2(20);
begin
    select emp_name
    into name
    from employee
    where emp_id = v_emp;
    dbms_output.put_line(name);
    v_name := name;
end;
/

set serveroutput on;
var test varchar2(20);
print test;

-- :연산자를 통해 test 변수에 저장
exec pro_select_emp2('&emp_id', :test);

2) FUNCTION

단일함수(각 row마다 적용되는)를 직접 만드는 것

procedure와 비슷하지만 실행결과를 되돌려 받을 수 있다는 점에서 차이가 있음

함수형이기 때문에 반환형, 매개변수 있음

select, insert, update문에서 사용할 수 있다.

create [or replace] function 함수명(매개변수, 매개변수,...)
return 리턴type
is
[변수 선언]
begin
	코드
end;
/

@ 생성 예
-- 문자를 넣으면 길이를 세어주는 함수
create or replace function myfunc(v_str varchar2)
return number
is
v_result number;
begin
    select length(v_str)
    into v_result
    from dual;
    
    return v_result;
end;
/
--실행하기
select myfunc('화이팅') From dual;

--emp_id를 전달받아 연봉을 반환해주는 함수만들기
create or replace function salary(v_id employee.emp_id%type) -- 참조타입으로 받기
return number
is
    result_salary number;
begin
    select (salary + (salary * nvl(bonus, 0))) * 12
    into result_salary
    from employee
    where emp_id = v_id;
    
    return result_salary;
end;
/

-- 전체 사원의 연봉 테이블 출력
select e.*, salary(e.emp_id) from employee e;
-- 입력받아서 한명 사원의 연봉 출력
select salary('&emp_id') from dual;

 

3. TRIGGER

테이블이나 뷰가 DML문(insert, update, delete)에 의해 변경될 경우, 자동으로 실행될 로직을 정의하여 저장, 실행하는 객체

입력된 데이터를 바로 저장, 주문량에 따라 재고량 update하는 등의 이벤트 생성시 사용됨

단, 에러 발생시 원인 찾기가 어려워서 안쓰기도 함

생성

  • 이전값은 :OLD.컬럼명으로 접근, 새로운 값은 :NEW.컬럼명으로 접근
    • insert: 새로운 값을 받아서 처리함
    • update: 이전값과 새로운 값을 모두 받아서 처리함
    • delete: 이전값을 처리함
CREATE [OR REPLACE] TRIGGER 트리거명
AFTER/BEFOR DML(INSERT, UPDATE, DELETE) ON 테이블명
FOR EACH ROW --행 추가마다 실행
BEGIN
	LOGIC
END;
/

-- EMPLOYEE테이블에 신입사원이 추가되면 신입사원이 입사했습니다 출력
CREATE OR REPLACE TRIGGER TRG_01
AFTER INSERT ON EMPLOYEE
FOR EACH ROW -- 다른것도 있지만 이거로 제일 많이 사용함
BEGIN
    DBMS_OUTPUT.PUT_LINE('신입사원 ' || :NEW.emp_name ||'이(가) 입사했습니다');
END;
/
--트리거 발동
insert into employee values('991', '전우치', '941111-123456', 'joen@j.com', 
        '01033333333', 'D3', 'J3', 'S1',30, 0.5, 200, sysdate, null, default);
--출력: 신입사원 전우치이(가) 입사했습니다.
  • (예) 트리거를 이용하여 상품 재고 관리 및 수정 히스토리 저장하기
--재고 관리 트리거 만들어보기
create table product(
    pcode number primary key,
    pname varchar2(20) not null,
    brand varchar2(20),
    price number check(price > 0),
    stock number default 0
);
create sequence seq_productno;

--입출력용 테이블
create table product_io(
    iocode number primary key,
    pcode number references product(pcode) not null, -- 필수관계
    iodate date default sysdate,
    amount number check(amount > 0),
    status varchar2(10) check(status in ('입고', '출고')) -- 숫자가 더 연산이 빠르긴 하지만 헷갈릴 수있음
);
create sequence seq_iono;
-- 제품등록
insert into product values(seq_productno.nextval, '맥북', '애플', 6000000, default);
insert into product values(seq_productno.nextval, '아이폰16', '애플', 2000000, default);
insert into product values(seq_productno.nextval, '반팔티', '스투시', 130000, default);
insert into product values(seq_productno.nextval, '샤넬백', '샤넬', 12000000, default);
select * from product;

--트리거 생성
create or replace trigger trg_productio
after insert on product_io
for each row -- 각 row 삽입시마다 실행
begin
    if :new.status = '입고' --상태가 입고면 재고를 수량만큼 더한다
        then update product set stock = stock + :new.amount 
        where pcode = :new.pcode;
    elsif :new.status = '출고' 
        then update product set stock = stock - :new.amount
        where pcode = :new.pcode;
    end if;
end;
/
insert into product_io values(seq_iono.nextval,1,default, 10, '입고');
insert into product_io values(seq_iono.nextval,1,default, 3, '출고');
select * from product; --맥북 재고 변동 확인 10->7

--변경 이력용 테이블
create taBle history_table(
  old_pname varchar2(20),
  new_pname varchar2(20),
  old_price number,
  new_price number,
  update_date date default sysdate
);
--수정 진행시 이력 테이블에 데이터를 저장하는 트리거 생성
create or replace trigger trg_productupdate
after update on product
for each row
begin
    insert into history_table values(:old.pname, :new.pname, :old.price, :new.price, default);
end;
/

select * from history_table;
select * from product;
update product set pname = '갤럭시s24', price = 1700000 where pcode = 2;

재고가 10에서 7로 변경되었다.
수정 이력 테이블에 정보가 저장되었다. 실제는 시간도 같이 기록되는 timestamp를 더 많이 이용한다.

 

4. CURSOR

결과가 여러 개의 행으로 구해지는 SELECT문을 처리하기 위해 실행 결과를 저장해놓은 객체

  • 명시적 커서라면 CURSOR ~ OPEN ~FETCH ~ CLOSE 단계로 진행된다.
💡 fetch ?
: 커서에서 원하는 값을 추출하는 것

1) 커서의 종류

  • 명시적(Explicit) 커서 : 사용자가 선언해서 생성하여 사용하는 커서로 주로 여러개 행을 처리하고자 할 경우에 사용한다.
  • 묵시적(Inplicit) 커서 : 오라클에서 자동으로 선언해주기 때문에 사용자는 생성 유무를 알 수 없다.

2) 커서의 속성

명시적 커서

커서명+속성 설명
%NOTFOUND 커서 영역 자료가 모두 fetch되어 다음 영역이 존재하지 않을 때 true 반환
%FOUND 커서 영역에 아직 fetch되지 않은 자료가 있을 때 true 반환
%ISOPEN 커서가 OPNE된 상태면 TRUE
%ROWCOUNT 커서가 얻어온 레코드의 개수로 일종의 카운터 역할을 한다.
- 커서가 오픈되면 0, 패치가 발생할 때마다 1씩 증가한다.

 

묵시적 커서

  • 위 속성에서 커서명 대신 SQL을 사용한다

3) 커서 생성

CUROSR 커서명
IS
SELECT 저장할_컬럼들
FROM 컬럼이_위치하는_테이블
WHERE 저장조건
BEGIN
OPEN 오픈할_커서명;
    LOOP
        FETCH 커서명 INTO 꺼내올_칼럼들;
        EXIT WHEN 커서명+속성;
        [출력문 등 반복 실행할 로직 작성]
    END LOOP;
    CLOSE 커서명; --커서 닫기
END/

 

5. PACKAGE

프로시저와 함수를 보다 효율적으로 관리하기 위해 패키지로 묶어서 관리를 한다.

@ 패키지 생성
CREATE OR REPLACE PACKAGE KH_PACK
IS
	PROCEDURE CUSOR_DEPT;
	FUNCTION BONUS_CALC(V_EMPID EMPLOYEE.EMP_ID%TYPE)
	RETURN NUMBER;
END;
/

@ 패키지 사용
EXEC KH_PACK.CUSOR_DEPT;
반응형
저작자표시 비영리 변경금지 (새창열림)

'Oracle DataBase' 카테고리의 다른 글

12. DB :: DB모델링 정리  (0) 2024.06.21
10. ORACLE :: oracle 내 객체 활용 정리(object)  (0) 2024.06.12
9. ORACLE :: DCL 구문(사용 권한 구문) 정리, 요약  (2) 2024.06.12
8. ORACLE :: DML구문(insert, upadate, delete) 정리  (0) 2024.06.12
7. ORACLE 정리 :: DDL구문(create, alter, drop)  (2) 2024.06.11
'Oracle DataBase' 카테고리의 다른 글
  • 12. DB :: DB모델링 정리
  • 10. ORACLE :: oracle 내 객체 활용 정리(object)
  • 9. ORACLE :: DCL 구문(사용 권한 구문) 정리, 요약
  • 8. ORACLE :: DML구문(insert, upadate, delete) 정리
JinHyung-dev
JinHyung-dev
틈틈이 기록하고 있습니다!!
  • JinHyung-dev
    JinHyung's 블로그
    JinHyung-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (34)
      • JAVA (18)
      • Oracle DataBase (12)
      • 프리코스 (4)
  • 인기 글

  • 반응형
  • 최근 댓글

  • 최근 글

  • 태그

    Java
    개발자
    백엔드
    DB
    자바
    요약
    공부
    SQL
    oracle
    정리
  • hELLO· Designed By정상우.v4.10.0
JinHyung-dev
11. ORACLE :: PL/SQL, PROCEDURE, FUNCTION,TRIGGER, CURSOR 정리
상단으로

티스토리툴바