WorkaHolic/MSSQL

MSSQL 제어문

2010. 2. 25. 16:35
반응형
1. if 문 
T-SQL 문의 실행에 대한 조건을 설정. IF 키워드와 그 조건 뒤의 T-SQL 문은 조건이 만족되는 경우 
(부울 식이 TRUE를 반환하는 경우)에만 실행된다. 선택적인 ELSE 키워드는 IF 조건이 만족되지 
않는 경우(부울 식이 FALSE를 반환하는 경우)에 실행되는 대체 T-SQL 문을 사용. 


* 한개의 if ~ else 블럭 사용 

USE dbsys 

IF (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 10) > (SELECT AVG(SAL) FROM EMP) 
BEGIN 
PRINT '10번부서의 연봉평균은 전체 평균보다는 높은 편이군요..!!' 
END -- BEGIN~END 반드시 써야한다. 없으면 한개의 T-SQL문에만 영향. 
ELSE 
PRINT '10번부서의 연봉평균은 전체 평균보다는 낮은 편이군요..!!' 


* 두개 이상의 if ~ else 블럭 사용 

IF (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 10) > 
(SELECT AVG(SAL) FROM EMP) 
BEGIN 
PRINT '10번부서의 연봉평균은 전체 평균보다는 높은 편이군요..!!' 
END 
ELSE 
IF (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 50) < 
(SELECT AVG(SAL) FROM EMP) 
BEGIN 
SELECT '10번,50번 둘다 전체연봉평균보다 낮네요..' 
END 


USE pubs 
go 

IF (SELECT AVG(price) FROM titles WHERE type = 'mod_cook') < $15 
BEGIN 
PRINT 'The following titles are excellent mod_cook books:' 
PRINT ' ' 
SELECT SUBSTRING(title, 1, 35) AS Title FROM titles 
WHERE type = 'mod_cook' 
END 
ELSE 
IF (SELECT AVG(price) FROM titles WHERE type = 'mod_cook') > $15 
BEGIN 
PRINT 'The following titles are expensive mod_cook books:' 
PRINT ' ' 
SELECT SUBSTRING(title, 1, 35) AS Title FROM titles 
WHERE type = 'mod_cook' 
END 


2. while 문 
SQL 문 또는 문 차단의 반복 실행에 대한 조건을 설정. 
문은 지정된 조건이 true인 한, 반복적으로 실행됨. 
WHILE 루프의 문 실행은 BREAK와 CONTINUE 키워드를 사용하여 루프 내에서 제어. 

* 중첩된 if~else 및 while로 break 및 continue 사용 
USE pubs 
GO 
WHILE (SELECT AVG(price) FROM titles) < $30 
BEGIN 
UPDATE titles 
SET price = price * 2 
SELECT MAX(price) FROM titles 
IF (SELECT MAX(price) FROM titles) > $50 
BREAK 
ELSE 
CONTINUE 
END 
PRINT 'Too much for the market to bear' 
GO 

* 커서가 있는 프로시저 내에서 WHILE 사용 
다음 WHILE 생성은 count_all_rows라는 이름의 프로시저의 구역. 
다음은 이 WHILE 생성이 커서와 함께 사용되는 함수인 
@@FETCH_STATUS의 반환 값을 테스트하는 예제. 
@@FETCH_STATUS가 -2, -1 또는 0을 반환하므로 세 가지 경우를 
모두 테스트해야한다. 저장 프로시저가 실행된 이후에 커서 
결과로부터 행을 삭제한 경우에는 해당 행을 건너뛴다. 
성공적으로 반입(0)된 경우, BEGIN...END 루프 내의 SELECT가 실행. 
/* 
@@FETCH_STATUS 함수의 값 
반환값 : 설명 
0 : FETCH 문이 성공 
-1 : FETCH 문이 실패 
-2 : 반입된 행이 없다. 
*/ 

USE pubs 
DECLARE tnames_cursor CURSOR 
FOR 
SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
OPEN tnames_cursor 
DECLARE @tablename sysname 
--SET @tablename = 'authors' 
FETCH NEXT FROM tnames_cursor INTO @tablename 
WHILE (@@FETCH_STATUS <> -1) 
BEGIN 
IF (@@FETCH_STATUS <> -2) 
BEGIN 
SELECT @tablename = RTRIM(@tablename) 
EXEC ('SELECT ''' + @tablename + ''' = count(*) FROM ' 
+ @tablename ) 
PRINT ' ' 
END 
FETCH NEXT FROM tnames_cursor INTO @tablename 
END 
CLOSE tnames_cursor 
DEALLOCATE tnames_cursor 



3. CASE 문 
조건 목록을 평가하고 가능한 여러 결과 식 중 하나를 반환. 

CASE는 두 가지 형식이 있다. 
- 단순 CASE 함수는 특정 식을 일련의 단순 식과 비교하여 결과를 결정. 
- 검색된 CASE 함수는 일련의 부울 식을 평가하여 결과를 결정. 

두 가지 형식 모두 선택 사항인 ELSE 인수를 지원. 

* 단순 CASE : SELECT문 내에서 동등성만 검사하고 다른 비교작업 수행 안함 
USE DBSYS 
GO 
SELECT DEPTNO, 
부서명 = 
CASE DEPTNO 
WHEN 10 THEN '부산의 총무부' 
WHEN 40 THEN '서울의 총무부' 
WHEN 70 THEN '제주의 총무부' 
END 
FROM DEPT 
WHERE DNAME = '총무부' 
ORDER BY 1 
GO 

* 검색된 CASE : 동등 검사, 부울검사 수행하여 결과를 낸다. 
SELECT DEPTNO, AVG(SAL) AS 부서별평균연봉, 
"부서별 평균연봉등급" = 
CASE 
WHEN AVG(SAL) <= 100000 THEN 
'평균연봉이 좀 낮은 부서군' 
WHEN AVG(SAL) > 100000 AND AVG(SAL) <= 130000 THEN 
'평균연봉이 보통인 부서군' 
WHEN AVG(SAL) > 130000 AND AVG(SAL) <= 150000 THEN 
'평균연봉이 좀 높은 부서군' 
ELSE '평균연봉이 꽤 높은 부서군' 
END 
FROM EMP WHERE DEPTNO IS NOT NULL 
GROUP BY DEPTNO 
ORDER BY 2 DESC 
GO 


USE pubs 
SELECT SUBSTRING((RTRIM(a.au_fname) + ' '+ 
RTRIM(a.au_lname) + ' '), 1, 25) AS Name, ta.title_id, 
Type = 
CASE 
WHEN SUBSTRING(ta.title_id, 1, 2) = 'BU' THEN 'Business' 
WHEN SUBSTRING(ta.title_id, 1, 2) = 'MC' THEN 'Modern Cooking' 
WHEN SUBSTRING(ta.title_id, 1, 2) = 'PC' THEN 'Popular Computing' 
WHEN SUBSTRING(ta.title_id, 1, 2) = 'PS' THEN 'Psychology' 
WHEN SUBSTRING(ta.title_id, 1, 2) = 'TC' THEN 'Traditional Cooking' 
END 
FROM titleauthor ta JOIN authors a ON ta.au_id = a.au_id 

-------------------------------------------------------------- 
SUBSTRING 함수 : 문자, 이진, 텍스트, 이미지 식의 일부를 반환 

형식 : SUBSTRING ( expression!! , start , length ) 

USE pubs 
SELECT au_lname, SUBSTRING(au_fname, 1, 1) 
FROM authors 
ORDER BY au_lname 

USE pubs 
SELECT pub_id, SUBSTRING(logo, 1, 10) AS logo, 
SUBSTRING(pr_info, 1, 10) AS pr_info 
FROM pub_info 
WHERE pub_id = '1756' 
-------------------------------------------------------------- 

-- 흐름 제어 키워드 -- 

1. BEGIN...END 사용 
BEGIN 및 END 문을 사용하여 여러 T-SQL 문을 논리 블록으로 그룹화. 
흐름 제어 문이 두 개 이상의 T-SQL 문 블록을 실행해야 하는 곳에서 
BEGIN 및 END 문을 사용. 

2. GOTO 
실행 흐름을 레이블로 변경. GOTO 다음에 이어지는 T-SQL 문을 건너뛰고 
레이블에서 처리를 계속 이어간다. GOTO 문과 레이블은 프로시저, 일괄 처리, 
명령문 블록 등 어디에서나 사용할 수 있다. GOTO 문은 중첩될 수 있다. 

레이블 정의 
label : 

실행 변경 
GOTO label 

CREATE TABLE GOTO1 
(ID INT, NAME CHAR(12), SAL INT) 
GO 
-- WHILE 문을 대신해 사용할 수 있는 GOTO 문 작성 
DECLARE @NO INT 
SET @NO = 0 
ADD_ID: 
BEGIN 
INSERT GOTO1 VALUES(@NO * 4 + 0, 'KIM', 700) 
INSERT GOTO1 VALUES(@NO * 4 + 1, 'KANG', 700) 
INSERT GOTO1 VALUES(@NO * 4 + 2, 'SEO', 700) 
INSERT GOTO1 VALUES(@NO * 4 + 3, 'PARK', 700) 
SET @NO = @NO + 1 
IF (@NO <> 1000) GOTO ADD_ID 
END 
GO 
-- 4000 개 입력 확인 
SELECT COUNT(*) FROM GOTO1 


3. RETURN 
쿼리나 프로시저를 무조건 종료. RETURN은 즉각적이고 완전하며 프로시저, 
일괄 처리, 명령문 블록에서 아무 때나 종료하는 데 사용할 수 있다. 
RETURN 다음에 있는 명령문을 실행되지 않는다. 


USE dbsys 

IF (SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 30) > (SELECT AVG(SAL) FROM EMP) 
BEGIN 
PRINT '10번부서의 연봉평균은 전체 평균보다는 높은 편이군요..!!' 
-- RETURN 
PRINT 'RETURN이 될려나?' 
END 
ELSE 
PRINT '10번부서의 연봉평균은 전체 평균보다는 낮은 편이군요..!!' 


4. WAITFOR 
문 블록, 저장 프로시저 또는 트랜잭션의 실행을 트리거하는 시간, 시간 간격 또는 이벤트를 지정. 

WAITFOR { DELAY 'time' | TIME 'time' } 
/* 
DELAY : 지정된 시간이 경과할 때까지 대기하도록 명령. 최대 24 시간까지 대기. 

'time' : 대기할 총 시간입니다. time은 datetime 데이터에서 사용할 수 있는 형식 중 한 가지를 
사용하여 지정하거나 로컬 변수로 지정할 수 있다. 날짜는 지정할 수 없으므로 
datetime 값의 날짜 부분은 허용되지 않는다. 

TIME : 지정된 시간까지 대기하도록 명령합니다. */ 
반응형