[๋ชฉ์ฐจ]
๐ ํจ์ : ์
๋ ฅ๊ฐ์ด ์๋ฌด๋ฆฌ ๋ง์๋ ์ถ๋ ฅ์ 1๊ฐ์ง๋ง ๋์จ๋ค.
๐ ๋จ์ผํํจ์ : ์
๋ ฅ๊ฐ ๋จ์ผํ
๋ฌธ์ํํจ์
์ซ์ํํจ์
๋ ์ง, ๋ฐํ, NULLํจ์
๋ค์ค์กฐ๊ฑดํจ์ : CASE ํํ์
๐ ๋ค์คํํจ์ : ์
๋ ฅ๊ฐ ๋ค์คํ
์ง๊ณํจ์, ๊ทธ๋ฃนํจ์
์๋์ฐํจ์
์๋์ฐํจ์๊ตฌ๋ฌธ
WINDOWING์ (SQL Server ์ง์ X)
๐ ์ ์ฐจํ SQL
PROCEDURE ํ๋ก์์
USER DEFINED FUNCTION ์ฌ์ฉ์ ์ ์ ํจ์
TRIGGER ํธ๋ฆฌ๊ฑฐ
๐ ํจ์ : ์ ๋ ฅ๊ฐ์ด ์๋ฌด๋ฆฌ ๋ง์๋ ์ถ๋ ฅ์ 1๊ฐ์ง๋ง ๋์จ๋ค.
๐ ๋จ์ผํํจ์ : ์ ๋ ฅ๊ฐ ๋จ์ผํ
๋ฌธ์ํํจ์
์ซ์ํํจ์
๋ ์ง, ๋ฐํ, NULLํจ์
๐ '201501' = TO_CHAR(์๋น์ค์ข ๋ฃ์ผ์, 'YYYYMM') : ์๋น์ค์ข ๋ฃ์ผ์์ ๋ ๊ณผ ์์ด 2015๋ 01์๊ณผ ๊ฐ์ ๊ฒ๋ค์ ์ฐพ์๋ธ๋ค. 01์ 01์ผ ~ 01์ 31์ผ์ด ํด๋น๋๋ค.
๐ 'TO_DATE('201501', 'YYYYMM') = ์๋น์ค์ข ๋ฃ์ผ์ : ์ง์ ๋์ง ์์ DD๋ 01๋ก ์ง์ ๋์ด 2015๋ 01์ 01์ผ์ด ์๋น์ค์ข ๋ฃ์ผ์์ ๊ฐ์ ๊ฒ๋ค์ ์ฐพ์๋ธ๋ค.
๋ค์ค์กฐ๊ฑดํจ์ : CASE ํํ์
๐ ๋ค์คํํจ์ : ์ ๋ ฅ๊ฐ ๋ค์คํ
์ง๊ณํจ์, ๊ทธ๋ฃนํจ์
์๋์ฐํจ์
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์นผ๋ผ๊ณผ ์นผ๋ผ์ ์ฐ์ฐ์ ์ฌ์ด๋ฐ๋ฉด ํ๊ณผ ํ์ ์ฐ์ฐ์ ๋งค์ฐ ์ด๋ ค์ ๋ค.
PL/SQL, T-SQL ๋ฑ์ ์ ์ฐจํ ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ฑฐ๋ INLINE VIEW๋ก ํด๊ฒฐํด์ผํ๋ ๊ฒ์ ํจ์๋ก ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
์๋์ฐํจ์๊ตฌ๋ฌธ
SELECT ์๋์ฐํจ์๋ช (๋งค๊ฐ๋ณ์) OVER (
[PARTITION BY ์นผ๋ผ๋ช ] //GROUP BY ์ญํ
[ORDER BY์ ] //ORDER BY ์ญํ
[WINDOWING์ ] //WHERE ์ญํ , SQL Server ์ง์ X
)
FROM ํ ์ด๋ธ๋ช ;
WINDOWING์ (SQL Server ์ง์ X)
์ข ๋ฅ | ์๋ฏธ | ์์ |
ROWS | ํ | |
CURRENT ROW | ํ์ฌ ํ | |
RANGE | ์นผ๋ผ๊ฐ | |
BETWEEN A AND B | A์ B์ฌ์ด ๊ฐ | RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ์นผ๋ผ๊ฐ์ ์ ํ์์ด ์ดํ๊ฐ์ผ๋ก ํ์ฌํ์ |
PRECEDING | ์ด์ ํ, ๋นผ๋ ๊ฐ | ROWS 2 PRECEDING : ํ์ 2ํ ์ RANGE 2 PRECEDING : ์นผ๋ผ๊ฐ์ -2 |
FOLLOWING | ๋ค์ ํ, ๋ํ๋ ๊ฐ | ROWS 2 FOLLOWING : ํ์ 2ํ ํ RANGE 2 FOLLOWING : ์นผ๋ผ๊ฐ์ +2 |
UNBOUNDED | ์ ํ์์ | ROWS UNBOUNDED PRECEDING : ์ฒซํ~ํ์ฌํ๊น์ง RANGE UNBOUNDED PRECEDING : ํ์ฌ ์นผ๋ผ๊ฐ ์ดํ ์ ๋ถ |
๐ ๋ค์ ์ค๋ช ์ค ์ ์ ํ ๊ฒ์?
1) PARTITION๊ณผ GROUP BY๊ตฌ๋ฌธ์ ์๋ฏธ์ ์ผ๋ก ์์ ํ ๋ค๋ฅด๋ค //์ ์ฌํ๋ค
2) SUM, MAX, MIN ๋ฑ๊ณผ ๊ฐ์ ์ง๊ณ WINDOW FUNCTION์ ์ฌ์ฉํ ๋ WINDOW ์ ๊ณผ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ง๊ณ์ ๋์์ด ๋๋ ๋ ์ฝ๋ ๋ฒ์๋ฅผ ์ง์ ํ ์ ์๋ค.
3) WINDOW FUNCTION ์ฒ๋ฆฌ๋ก ์ธํด ๊ฒฐ๊ณผ ๊ฑด์๊ฐ ์ค์ด๋ค ์ ์๋ค //๊ฒฐ๊ณผ๊ฑด์๋ ์๊ด์๋ค.
4) GROUP BY ๊ตฌ๋ฌธ๊ณผ WINDOW FUNCTION์ ๋ณํํ์ฌ ์ฌ์ฉํ ์ ์๋ค. //๋ณํ ๋ถ๊ฐํ๋ค
๐ ์ ์ฐจํ SQL
SQL๋ ์ ์ฐจ ์งํฅ์ ์ธ ํ๋ก๊ทธ๋จ์ด ๊ฐ๋ฅํ๋๋ก ์ ์ฐจํ SQL์ ์ ๊ณตํ๊ณ ์๋ค.
์ฐ์์ ์ธ ์คํ์ด๋ ์กฐ๊ฑด์ ๋ฐ๋ฅธ ๋ถ๊ธฐ์ฒ๋ฆฌ๋ฅผ ์ด์ฉํ์ฌ ๋ชจ๋์ ์์ฑํ ์ ์๋ค.
์ ์ฅ๋ชจ๋๋ก PROCEDURE, USER DEFINED FUNCTION, TRIGGER๋ฅผ ์ ๊ณตํ๋ค.
๊ตฌ๋ถ | PROCEDURE ํ๋ก์์ | FUNCTION ํจ์ | TRIGGER ํธ๋ฆฌ๊ฑฐ |
์ค๋ช | ํน์ ๋ก์ง์ ์ฒ๋ฆฌํ๋ ํ๋ก๊ทธ๋จ | ํน์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๋ ํ๋ก๊ทธ๋จ | INSERT, UPDATE, DELETE ์์
์ ์๋์ผ๋ก ์คํ๋๋ ํ๋ก๊ทธ๋จ |
Oracle ๊ตฌ๋ฌธ |
CREATE [or REPLACE] Procedure ํ๋ก์์ ๋ช
( ๋งค๊ฐ๋ณ์๋ช [MODE] ๋ฐ์ดํฐํ์ , .... ) IS [AS] ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ EXCEPTION ์๋ฌ ๋ฐ์ ์ ๋ด์ฉ END; / |
CREATE Function ํจ์๋ช
(๋งค๊ฐ๋ณ์๋ช
๋ฐ์ดํฐํ์
) RETURN ๋ฐ์ดํฐํ์ IS[AS] ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ RETURN ๋ฐํํ ๊ฐ EXCEPTION ์์ธ์ ๋ด์ฉ END / |
CREATE Trigger ํธ๋ฆฌ๊ฑฐ๋ช
BEFORE or AFTER INSERT or UPDATE or DELETE ON ํ ์ด๋ธ๋ช [FOR EACH ROW] [WHEN ์กฐ๊ฑด์] ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ END / |
SQL Server ๊ตฌ๋ฌธ | CREATE Procedure ํ๋ก์์ ๋ช
@๋งค๊ฐ๋ณ์๋ช ๋ฐ์ดํฐํ์ [MODE], .... AS ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ ERROR ์๋ฌ ๋ฐ์ ์ ๋ด์ฉ END; |
CREATE Function ํจ์๋ช
(๋งค๊ฐ๋ณ์๋ช
๋ฐ์ดํฐํ์
) RETURNS ๋ฐ์ดํฐํ์ AS ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ RETURN ๋ฐํํ ๊ฐ END |
CREATE Trigger ํธ๋ฆฌ๊ฑฐ๋ช
ON ํ ์ด๋ธ๋ช FOR or AFTER or INSTEAD OF INSERT or UPDATE or DELETE AS ๋ณ์์ ์ธ BEGIN ์คํ๋ด์ฉ END; |
์คํ๋ฐฉ๋ฒ | EXECUTE ํ๋ก์์ ๋ช ( ๋งค๊ฐ๋ณ์ ) | ํจ์๋ช ( ๋งค๊ฐ๋ณ์ ) | DBMS์ ์ํด ์๋์คํ |
RETURN | RETURN ํ์ X | RETURN ํ์ O | ์ฌ์ฉ์ํจ |
TCL | BEGIN~END์ COMMIT, ROLLBACK ์ฌ์ฉ O |
BEGIN~END์ COMMIT, ROLLBACK ์ฌ์ฉ X |
PROCEDURE ํ๋ก์์
Oracle | SQL Server | |
์ ์ฐจํ SQL | PL(Procedural Language)/SQL BLOCK ๊ตฌ์กฐ๋ก ๋์ด์์ด ๊ฐ ๊ธฐ๋ฅ๋ณ๋ก ๋ชจ๋ํ๊ฐ ๊ฐ๋ฅํ๋ค. |
T-SQL |
Stored Procedure ์์ฑ๋ฐฉ๋ฒ |
CREATE [or REPLACE] Procedure ํ๋ก์์ ๋ช
( ๋งค๊ฐ๋ณ์๋ช [MODE] ๋ฐ์ดํฐํ์ , .... ) IS [AS] ๋ณ์์ ์ธ BEGIN ์คํํ ๋ด์ฉ EXCEPTION ์๋ฌ ๋ฐ์ ์ ๋ด์ฉ END; / |
CREATE Procedure ํ๋ก์์ ๋ช
@๋งค๊ฐ๋ณ์๋ช ๋ฐ์ดํฐํ์ [MODE], .... AS ๋ณ์์ ์ธ BEGIN ์คํํ ๋ด์ฉ ERROR ์๋ฌ ๋ฐ์ ์ ๋ด์ฉ END; |
๋งค๊ฐ๋ณ์ MODE - IN : ์ธ๋ถ์์ ๋งค๊ฐ๋ณ์ ๋ฐ์ ๋ ์ฌ์ฉ - OUT : ํ๋ก์์ ๊ฒฐ๊ณผ ๋ฐํํ ๋ ์ฌ์ฉ - INOUT : IN๊ณผ OUT์ ๋ด์ฉ ๋์์ ์ํ / : ํ๋ก์์ ๋ฅผ ์ปดํ์ผํ๋๋ก ๋ช ๋ นํ๋ ๊ฒ. |
๋งค๊ฐ๋ณ์ MODE - VARING : ๊ฒฐ๊ณผ ์งํฉ์ด ์ถ๋ ฅ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉ๋๋๋ก - DEFAULT : ๋งค๊ฐ๋ณ์ ๊ฐ์ด ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฒ๋ฆฌ - OUT/OUTPUT : ํ๋ก์์ ๊ฒฐ๊ณผ ๋ฐํ - READONLY : ๋งค๊ฐ๋ณ์๋ฅผ ์์ ํ ์ ์๋ค |
|
Stored Procedure ์์ ๋ฐฉ๋ฒ |
REPLACE Procedure ํ๋ก์์ ๋ช
... ์ ์์ฑํ๋ฉด ์๋ก์ด ๋ด์ฉ์ผ๋ก ๋ฎ์ด์ฐ๊ฒ๋๋ค. |
ALTER Procedure .... ๋ก ๋ณ๊ฒฝํ๋ค. |
Stored Procedure ์ญ์ ๋ฐฉ๋ฒ |
DROP Procedure ํ๋ก์์ ๋ช ; | DROP Procedure ํ๋ก์์ ๋ช ; |
Stored Procedure ์คํ๋ฐฉ๋ฒ |
EXECUTE ํ๋ก์์ ๋ช (๋งค๊ฐ๋ณ์, ...); | EXECUTE ํ๋ก์์ ๋ช ๋งค๊ฐ๋ณ์, ...; |
์์ | CREATE Procedure p_DEPT_insert ( v_DEPTNO in number, v_dname in varchar2, v_loc in varchar2, v_result out varchar2 ) IS cnt number := 0; --SCALAR ๋ณ์ cnt : ์์๋ฐ์ดํฐ 1๊ฐ ์ ์ฅ๊ฐ๋ฅ --๋์ ์ฐ์ฐ์ := BEGIN SELECT COUNT(*) INTO CNT FROM DEPT --์ ๋ ฅ๋ฐ์ ๋ถ์์ฝ๋๊ฐ ์กด์ฌํ๋์ง ํ์ธ --SELECT๋ฌธ ๊ฒฐ๊ณผ๊ฐ ๋ฐ๋์ ์์ด์ผํ๋ค. WHERE DEPTNO = v_DEPTNO AND ROWNUM = 1; if cnt >0 then --๋ถ์์ฝ๋๊ฐ ์กด์ฌํ๋ฉด v_result := '์ด๋ฏธ ๋ฑ๋ก๋ ๋ถ์๋ฒํธ์ด๋ค'; else --๋ถ์์ฝ๋๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด INSERT INTO DEPT (DEPTNO, DNAME, LOC) VALUES (v_DEPTNO, v_dname, v_loc); -- ๋ ์ฝ๋ ์ ๋ ฅ COMMIT; --์ปค๋ฐ v_result := '์ ๋ ฅ ์๋ฃ!!'; end if; EXCEPTION --์๋ฌ๋ฐ์ ์ WHEN OTHERS THEN ROLLBACK; v_result := 'ERROR ๋ฐ์'; END; / |
CREATE Procedure dbo.p_DEPT_insert @v_DEPTNO int, @v_dname varchar(30), @v_loc varchar(30), @v_result varchar(100) OUTPUT AS DECLARE @cnt int -- ๋ณ์ ์ ์ธ SET @cnt = 0 --SCALAR ๋ณ์ cnt : ์์๋ฐ์ดํฐ 1๊ฐ ์ ์ฅ๊ฐ๋ฅ --๋์ ์ฐ์ฐ์ = BEGIN SELECT @cnt=COUNT(*) FROM DEPT --์ ๋ ฅ๋ฐ์ ๋ถ์์ฝ๋๊ฐ ์กด์ฌํ๋์ง ํ์ธ --SELECT๋ฌธ ๊ฒฐ๊ณผ๊ฐ ์์ด๋ ๋๋ค. WHERE DEPTNO = @v_DEPTNO IF @cnt >0 --๋ถ์์ฝ๋๊ฐ ์กด์ฌํ๋ฉด BEGIN SET @v_result = '์ด๋ฏธ ๋ฑ๋ก๋ ๋ถ์๋ฒํธ์ด๋ค' RETURN END ELSE --๋ถ์์ฝ๋๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด BEGIN BEGIN TRAN INSERT INTO DEPT (DEPTNO, DNAME, LOC) VALUES (@v_DEPTNO, @v_dname, @v_loc) -- ๋ ์ฝ๋ ์ ๋ ฅ IF @@ERROR<>0 BEGIN ROLLBACK --์๋ฌ๋ฐ์ ์ SET @v_result = 'ERROR ๋ฐ์' RETURN END ELSE BEGIN COMMIT --์ปค๋ฐ SET @v_result = '์ ๋ ฅ ์๋ฃ!!' RETURN END END END |
FUNCTION ํจ์
ํจ์๋ ํ๋ก์์ ์ ๋ฌ๋ฆฌ, RETURN์ ์ด์ฉํด์ ๊ฐ์ ๋ฐ๋์ ๋ฐํํด์ค๋ค.
Oracle | SQL Server | |
ABS ๊ตฌํ ์์ |
CREATE Function UTIL_ABS (v_input in number) return NUMBER IS v_return number := 0; BEGIN if v_input <0 then v_return := v_input * -1; else v_return := v_input; end if; RETURN v_return; END; / |
CREATE Function dbo.UTIL_ABS (@v_input int) RETURNS int AS BEGIN DECLARE @v_return int SET @v_return=0 IF @v_input <0 SET @v_return = @v_input * -1 ELSE SET @v_return = @v_input RETURN @v_return; END |
TRIGGER ํธ๋ฆฌ๊ฑฐ
ํธ๋ฆฌ๊ฑฐ๋ ํน์ ํ ์ด๋ธ์ INSERT, UPDATE, DELETE ๋ฑ์ด ์ํ๋์์ ๋
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์๋์ผ๋ก ๋์ํ๊ฒํ๋ ํ๋ก๊ทธ๋จ์ด๋ค.
ํธ๋ฆฌ๊ฑฐ๋ ํธ๋์ญ์ ์์์ ์ผ์ด๋๋ ์์ ์ผ๋ก ๋ณผ์๋์๋ค.
๋ฐ๋ผ์ ROLLBACK์ ํ๋ฉด ํธ๋ฆฌ๊ฑฐ ์์ ๋ด์ญ๋ ๋ชจ๋ ์ทจ์๋๋ค!
Oracle | SQL Server | |
์์ | CREATE Trigger SUMMARY_SALES AFTER INSERT --๋ ์ฝ๋๊ฐ ์ ๋ ฅ๋ ํ ํธ๋ฆฌ๊ฑฐ์คํ ON ORDER_LIST -- ํ ์ด๋ธ์ ํธ๋ฆฌ๊ฑฐ ์ค์ FOR EACH ROW --๊ฐ ํ๋ง๋ค ํธ๋ฆฌ๊ฑฐ ์คํ DECLARE o_date ORDER_LIST.order_date%TYPE; o_prod ORDER_LIST.product%TYPE; BEGIN o_date := :NEW.order_date; --NEW ์ ๊ทํ์ ์ ๋ณด o_prod := :NEW.product; UPDATE SALES_PER_DATE SET qty = qty + :NEW.qty, amount = amount + :NEW.amount WHERE sale_date = o_date AND product = o_prod; if SQL%NOTFOUND then INSERT INTO SALES_PER_DATE VALUES(o_date, o_prod, :NEW.qty, :NEW.amount); end if; END; / |
CREATE Trigger dbo.SUMMARY_SALES ON ORDER_LIST -- ํ ์ด๋ธ์ ํธ๋ฆฌ๊ฑฐ ์ค์ AFTER INSERT --๋ ์ฝ๋๊ฐ ์ ๋ ฅ๋ ํ ํธ๋ฆฌ๊ฑฐ์คํ AS DECLARE @o_date DATETIME,@o_prod INT, @qty int, @amount int BEGIN SELECT @o_date=order_date, @o_prod=product, @qty=qty, @amount=amount FROM inserted -- inserted ์ ๊ทํ์ ์ ๋ณด UPDATE SALES_PER_DATE SET qty = qty + @qty, amount = amount + @amount WHERE sale_date = @o_date AND product = @o_prod; IF @@ROWCOUNT=0 INSERT INTO SALES_PER_DATE VALUES(@o_date, @o_prod, @qty, @amount) END |