제1회 tech net sql server 2005 t sql enhancements

48
Hands-On Lab 실실 실실실 SQL Server™ 2005: T-SQL Enhancements 실실

Upload: beamofhope

Post on 25-Jan-2015

754 views

Category:

Technology


4 download

DESCRIPTION

 

TRANSCRIPT

Page 1: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

Hands-On Lab

실습 메뉴얼

SQL Server™ 2005:T-SQL Enhancements 실습

Page 2: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

2

목 차

실습 메뉴얼.......................................................................................................................................................................... 1

SQL Server™ 2005:.................................................................................................................................................................1

T-SQL Enhancements 실습....................................................................................................................................................1

연습 0 실습 설정................................................................................................................................................................. 4

Chapter 1 -연습 1: varchar(max)...........................................................................................................................................5

Chapter 1 -연습 2: 행 오버플로우 지원...........................................................................................................................6

Chapter 1 -연습 3: Snaptshot isolation level..........................................................................................................................7

Chapter 1 -연습 4: 예외 처리..............................................................................................................................................9

Chapter 2 -연습 1: TOP 연산자 기능 향상.....................................................................................................................12

Chapter 2 -연습 2: 문자셋 지원.......................................................................................................................................14

Chapter 2 -연습 3: 파티션(분할) 테이블 구성 및 성능테스트...................................................................................16

Chapter 3 -연습 1: DDL 트리거를 이용한 로깅 및 테이블 변경 방지.......................................................................19

Chapter 3 -연습 2: DDL 트리거를 이용한 MASTER DATABASE 백업자동화............................................................21

Chapter 3 -연습 3: XML 향상..............................................................................................................................................24

Chapter 4 -연습 1: RANKING 함수들을 이용해서, 쉽게 순위 구하기.......................................................................25

Chapter 4 -연습 2: PIVOT & UNPIVOT................................................................................................................................27

Chapter 4 -연습 3: 시스템 정보 보기...............................................................................................................................28

Chapter 4 -연습 4: DMV....................................................................................................................................................... 30

Chapter 5 -연습 1: 원격쿼리 향상....................................................................................................................................33

Chapter 5 -연습 2: tablesample...........................................................................................................................................34

Chapter 5 -연습 3: cascade (연계참조 무결성)..............................................................................................................35

Chapter 5 -연습 4: OUTPUT................................................................................................................................................37

Chapter 6 -연습 1: CTE....................................................................................................................................................... 39

Chapter 6 -연습 2: Apply 연산자.......................................................................................................................................41

Chapter 6 -연습 3: 쿼리 힌트............................................................................................................................................44

Page 3: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

3

SQL Server 2005 T-SQL Enhancements

이 실습을 끝마치고 나면, 여러분은 다음과 같은 작업을 하실 수 있습니다:

SQL Server 2005 에서의 향상된 T-SQL 기능에 대해 이해할 수 있다.

SQL Server 2005 에서의 향상된 T-SQL 기능을 사용하는 법을 직접 습득하여 실무에서 바로 적용할 수 있다.

이 실습은 이 장의 개념에 초점을 맞추어 작성되었습니다. 따라서 이 실습은 마이크로소프트 보안 권고사항에 정확히 부합하지 않을 수 있습니다.

SQL Server 2005 는 전통적인 데이터베이스 기반에 개발환경이 통합된 플랫폼으로 SQL Server 2005 T-SQL 엔진의 변화에 대해서 이해하고 있어야만 개발과 유지보수 시 최상의 프로젝트를 진행할 수 있습니다. 이번 강좌에서는 가장 필요하고 실무에서 자주 사용되는 혹은 되어야 할 SQL Server 2005 T-SQL 기능과 사용법에 대해서 설명할 것이다.

이번 실습을 시작하기 전에 여러분은 다음과 같은 지식을 갖추고 있어야 한다:

기본적인 윈도우 운영 환경

기본적인 T-SQL 사용 경험

SQL Server 2000 혹은 2005 개발 경험

연습 0 실습 설정

실습 환경 설정

목표Note 시나리오 선수조건 예상 소요시간: 210 분

Page 4: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

4

- SQL Server 2005 (Enterprise or Developer or Evaluation) Edition

- 실습을 위한 예제용 데이터베이스인 Adventureworks 가 있어야 한다. 실습 시 설치하도록 한다. 설치되어 있지 않다면 아래 주소에서 “AdventureworksDB CI .msi ” 파일을 다운로드 해서 설치하도록 한다.

http://www.microsoft.com/downloads/details.aspx?familyid=E719ECF7-9F46-4312-AF89-6AD8702E4E6E&displaylang=en

- 운영체제 계정은 각자 보유한 PC 사용자 계정을 사용한다.

- SQL Server 로그인 계정은 각자 보유한 PC 에 설치된 데이터베이스 계정을 사용한다.

- 실습(*.sql)파일을 저장하기 위한 폴더를 사전에 생성한다. “D:\TSQL”. D 드라이브가 없다면, “C:\TSQL” 폴더를 생성한다.

- 특별히 데이터베이스를 지정하지 않는 이상, 모든 SQL 명령문은 “ADVENTUREWORKS” 데이터베이스 연결에서 실행하도록 한다.

Chapter 1 -연습 1: varchar(max)

시나리오SQL Server 2005 의 새로운 데이터형식인 varchar(max)에 대한 이점과 사용법을 살펴본다. 실습을 하기 위해, 다음 단계들을 수행한다.

Task 1: varchar(max) 데이터 타입 사용방법과 효과확인하기

1. SSMS(SQL Server management studio)를 실행하고, 쿼리실행창을 연 후 데이터베이스를 Adventureworks 로 변경한다.

2. 예제를 위한 테이블생성과 데이터를 입력한다

CREATE TABLE DBO.VARMAX_01 (VID INT, VMEMO NVARCHAR(MAX))GOINSERT INTO DBO.VARMAX_01(VID,VMEMO)

VALUES(1,REPLICATE(cast(N'Guidelines and recommendations for' as Nvarchar(max)),10000))INSERT INTO DBO.VARMAX_01(VID,VMEMO)

VALUES(2,REPLICATE(cast(N'Guidelines and recommendations for' as Nvarchar(max)),10000))GO

3. text 에서 사용할 수 없는 함수가 사용됨을 확인한다(COL_LENGTH, CHARINDEX, PATINDEX, LEN, DATALENGTH, SUBSTRING)

SELECT DATALENGTH(VMEMO) FROM DBO.VARMAX_01SELECT SUBSTRING(VMEMO,10000,10) FROM DBO.VARMAX_01

Task 2: text 컬럼에서의 substring 함수사용을 확인한다.

1. 예제를 위한 테이블생성과 데이터를 입력한다

CREATE TABLE DBO.TEXT_01 (TID INT, TMEMO NTEXT)GOINSERT INTO DBO.TEXT_01(TID,TMEMO) VALUES(1,REPLICATE(N'Guidelines and

Page 5: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

5

recommendations for',10000))INSERT INTO DBO.TEXT_01(TID,TMEMO) VALUES(2,REPLICATE(N'Reflectors are vital safety components',10000))2. DATALENGTH, SUBSTRING 함수사용을 시도해본다. 정상적인 데이터가 출력되지 않는 것을 확인한다

SELECT DATALENGTH(TMEMO) FROM DBO.TEXT_01SELECT SUBSTRING(TMEMO,10000,10) FROM DBO.TEXT_01

Task 3: VARCHAR(MAX) 의기본속성을확인한다

1. 예제를 위한 테이블생성과 데이터를 입력한다

CREATE TABLE DBO.VARMAX_02 (VID INT, VMEMO VARCHAR(MAX))GOSELECT NAME, large_value_types_out_of_row

FROM SYS.TABLES WHERE NAME = 'VARMAX_02'

Chapter 1 -연습 2: 행 오버플로우 지원

시나리오SQL Server 2005 에서 새롭게 지원하는 행 오버플로우가 구현되는 것을 확인한다.

Task 1: 실습을 위한 테이블을 생성한다.

1. 실습을 위한 테이블을 생성한다

CREATE TABLE DBO.ROWOVER( RID INT, R1 VARCHAR(5000), R2 VARCHAR(5000))GO

Task 2: 페이지크기의 한계인 8060 bytes 한계를 넘는 데이터가 잘 입력되는지 확인한다.

1. 페이지크기의 한계인 8060 한계를 넘는 데이터가 잘 입력되는지 확인한다

INSERT INTO DBO.ROWOVER(RID, R1, R2) VALUES(1, REPLICATE('A',5000), REPLICATE('A',5000))

GO

Task 3: 특정테이블에 대해, 오버플로우된 행이 있는지 dm_db_index_physical_stats 동적뷰(DMV)를 이용해서 확인한다. alloc_unit_type_desc 컬럼 값에 'ROW_OVERFLOW_DATA' 값이 있다면 오버플로우된 행이 있는 것이다

1. 동적뷰를 이용해서 확인한다

SELECT *FROM sys.dm_db_index_physical_stats(db_id('Adventureworks'), object_id('rowover'), NULL, NULL , 'LIMITED')SELECT *

Page 6: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

6

FROM sys.dm_db_index_physical_stats(db_id('Adventureworks'), object_id('VARMAX_01'), NULL, NULL , 'LIMITED')

첫 번째 문장에서는 오버플로우된 행이 있음을 출력한다.

Chapter 1 -연습 3: Snaptshot isolation level

시나리오SQL Server 2005 에서 새롭게 지원하는 격리수준인 Snapshot isolation level 에 대한 구현방법과 의미를 알아본다.

Task 1: 실습을 위한 데이터베이스를 생성하고, 옵션을 설정한다.

1. 데이터베이스를 생성한다

Use Master

GO

CREATE DATABASE SNAPSHOT_ONGO

2. DB 옵션을 ALLOW_SNAPSHOT_ISOLATION 으로 설정한다. 기본값은 OFF 이다

ALTER DATABASE SNAPSHOT_ONSET ALLOW_SNAPSHOT_ISOLATION ON

GO

3. 옵션변경이 잘 되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다

USE SNAPSHOT_ONGO

DBCC USEROPTIONSGOSELECT NAME, snapshot_isolation_state,

is_read_committed_snapshot_on FROM sys.databases WHERE NAME = 'SNAPSHOT_ON'

4. 다음을 수행하여 트랜잭션을 시작한다. 현재 연결을 SESSION1 이라 명명한다

--SESSION1)USE SNAPSHOT_ONGOCREATE TABLE DBO.SNAP_01 (SID INT, SNAME CHAR(10))GO

Page 7: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

7

INSERT INTO DBO.SNAP_01(SID,SNAME) VALUES(1,'JONES')GOBEGIN TRAN

UPDATE DBO.SNAP_01SET SNAME = 'NANCY'

5. 트랜잭션이 잘 시작되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다

--SESSION1)SELECT * FROM sys.dm_tran_active_snapshot_database_transactions

SELECT @@TRANCOUNT

6. 새로운 쿼리실행창을 열어서 다음 문장을 실행한다. BEFORE IMAGE 즉, 트랜잭션이 실행되기 전의 스냅샷을 출력하는 것을 확인한다

--SESSION2)SET TRANSACTION ISOLATION LEVEL SNAPSHOTGOSELECT * FROM DBO.SNAP_01

7. 트랜잭션을 시작했던 쿼리실행창에서 다음을 실행한다

--SESSION1)ROLLBACK8. SESSION2 쿼리실행창을 닫는다

9. 같은 과정을 스냅샷옵션 변경 없이 실행해 본다. 잠금으로 인해 blocked 되는 것을 확인할 수 있다

Page 8: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

8

Chapter 1 -연습 4: 예외 처리

시나리오SQL Server 2005 에서 새롭게 지원하는 예외처리 기능인 try… catch 문을 실행하는 방법을 알아본다.

Task 1: 단순오류 발생 시 예외처리프로세스를 알아본다

1. 예제를위한테이블과데이터를준비한다

CREATE TABLE DBO.TRYCATCH ( TID TINYINT, TNAME CHAR(10))GOINSERT INTO DBO.TRYCATCH(TID,TNAME)

VALUES(1,'JONES')GO

2. 오류가 발생하도록 INSERT 문장을 실행하고, 예외처리블록을 지정하여 오류를 출력하도록 한다. 어떤 오류가 발생하는지 확인하도록 한다. 아래 명령은 일괄처리로 실행되어야 하므로, 모든 영역을 선택해서 한번에 실행하도록 한다

DECLARE @TRANCNT TINYINTBEGIN TRANSACTION

BEGIN TRYINSERT INTO DBO.TRYCATCH(TID,TNAME) VALUES (300, 'INDIANA')WAITFOR DELAY '00:00:05'SET @TRANCNT = @@TRANCOUNTSELECT COUNT(*) AS '총갯수' FROM TRYCATCHCOMMIT

END TRYBEGIN CATCH

SELECT ERROR_NUMBER() AS 오류번호SELECT ERROR_MESSAGE() AS 오류메시지SELECT ERROR_SEVERITY() AS 심각도SELECT ERROR_STATE() AS 오류상태SELECT ERROR_LINE() AS 오류발생라인SELECT ERROR_PROCEDURE() AS 오류발생프로시저명ROLLBACK

END CATCHSELECT @TRANCNT AS '@@TCount'

Page 9: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

9

GO

Task 2: DEADLOCK 발생 시 예외처리하기

1. 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되, SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다

--SESSION1)BEGIN TRANSACTIONBEGIN TRY INSERT DBO.TRYCATCH VALUES (10, 'AAAA') WAITFOR DELAY '00:00:05' SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH COMMITEND TRYBEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACKEND CATCHSELECT @@TRANCOUNT AS '트랜잭션중첩수'

--SESSION2)BEGIN TRANSACTIONBEGIN TRY INSERT DBO.TRYCATCH VALUES (20, 'BBBB') WAITFOR DELAY '00:00:05' SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH COMMITEND TRYBEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACKEND CATCHSELECT @@TRANCOUNT AS '트랜잭션중첩수'

2. 어떤 오류가 발생되었는지 확인한다. 오류는 발생하지 않았고, 트랜잭션은 실행되었다

--SESSION1) 에서 결과창의 데이터를 확인만 한다3. SESSION1 에서 실행한 트랜잭션이 제대로 COMMIT 되었는지 확인한다. COMMIT 되었다

--SESSION1)SELECT * FROM DBO.TRYCATCH4. SESSION2 에는 어떤 오류가 발생되었는지 확인한다. 교착상태오류(1205 번)가 발생했고, 트랜잭션은

ROLLBACK 되었다

--SESSION2) 에서 결과창의 데이터를 확인만 한다5.

--SESSION1)

Task 3: DEADLOCK 발생 시 트랜잭션 재시도하기, 이제 교착상태가 발생하면 ROLLBACK 하고 종료하는 것이 아닌, 트랜잭션을 재시도하도록 루틴을 작성해보자. 이 루틴은 2005 에서 데이터일관성을 위해 deadlock 처리를 어떻게 할 수 있는지에 대한 좋은 예가 된다

Page 10: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

10

1. 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되, SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다

--SESSION1)DECLARE @Tries tinyintSET @Tries = 1WHILE @Tries <= 3BEGIN BEGIN TRANSACTION BEGIN TRY INSERT DBO.TRYCATCH VALUES (10, 'AAAA') WAITFOR DELAY '00:00:05'

SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH COMMIT BREAK END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACK SET @Tries = @Tries + 1 CONTINUE END CATCHEND

--SESSION2)DECLARE @Tries tinyintSET @Tries = 1WHILE @Tries <= 3 -- deadlock 이발생해도트랜잭션을종료하지않고3번을재시도하도록한다. 재시도횟수는변경할수있다BEGIN BEGIN TRANSACTION BEGIN TRY INSERT DBO.TRYCATCH VALUES (20, 'BBBB’) WAITFOR DELAY '00:00:05'

SELECT COUNT(*) AS '총갯수' FROM TRYCATCH COMMIT BREAK END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACK SET @Tries = @Tries + 1 CONTINUE END CATCHEND

2. SESSION2 에서 교착상태가 발생되었을 때 어떻게 실행되었는지 확인한다. 재시도 횟수를 늘려서 교착상태 발생 시에도 트랜잭션의 일관성을 보장하도록 할 수 있다

SELECT * FROM DBO.TRYCATCH

Page 11: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

11

Chapter 2 -연습 1: TOP 연산자 기능 향상

시나리오SQL Server 2005 에서 새롭게 지원하는 변수와 함께 TOP 연산자를 사용하는 방법에 대해서 알아본다.

Task 1: SQL Server 2000 과 2005 에서 변수와 함께 top 연산자를 사용해 본다. 2000 에 대한 실습자의 환경이 준비되지 않은 경우에는, 강사가 2000 을 위한 예제는 데모로 실행해서 확인하고, 2005 를 위한 예제는 모두 실행해서 확인한다.

1. 변수를 이용하여 TOP 연산자를 사용하는 로직을 먼저 SQL Server 2000 에서실행한다. 오류가 발생하는 것을 확인할 수 있다

DECLARE @A INTSELECT @A=COUNT(EMPLOYEEID) FROM NORTHWIND.dbo.EmployeesSELECT TOP(@A-2) * FROM NORTHWIND.dbo.Employees

ORDER BY EMPLOYEEID DESCGO

2. 1 번과 같은 로직을 사용해서 2005 환경에서 실행한다. 2005 에는 NORTHWIND 데이터베이스가 없으므로 ADVENTUREWORKS 데이터베이스의 PERSON.ADDRESS 테이블을 대신 이용하도록 한다. 오류 없이 잘 실행되는 것을 확인할 수 있다

DECLARE @A INTSELECT @A=COUNT(ADDRESSID) FROM ADVENTUREWORKS.PERSON.ADDRESSSELECT TOP(@A-2) * FROM ADVENTUREWORKS.PERSON.ADDRESS

ORDER BY ADDRESSID DESCGO

Task 2: UPDATE 에서 TOP 사용하기

1. SQL Server 2000 환경에서 TOP 을이용한 UPDATE 를실행해본다. 지원하지않는기능이므로, 오류가발생하는것을확인할수있다

UPDATE TOP (2) NORTHWIND.DBO.EMPLOYEESSET EMPLOYEEID = 276WHERE EMPLOYEEID IN (1,2,3,4,5)

Page 12: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

12

GO

2. SQL Server 2005 환경에서 TOP 을 이용한 UPDATE 를 실행한다. 잘 실행된다

BEGIN TRANUPDATE TOP (2) ADVENTUREWORKS.PERSON.ADDRESS

SET AddressLine2 = 'Daehan Bldg. 3th'WHERE ADDRESSID IN (1,2,3,4,5)

3. 변경된 데이터를 확인한다. 그러나 실제 변경된 데이터는 임의의 데이터이며 ,어떤 데이터를 변경할 것인지, 우리는 결정할 수 없다

SELECT * FROM ADVENTUREWORKS.PERSON.ADDRESSWHERE ADDRESSID IN (1,2,3,4,5)

4. 작업을 취소한다

ROLLBACK TRANSACTIONGO

5. 우리가 원하는, 즉 의미 있는 데이터를 변경하기 위해서는 다음과 같은 로직을 사용해야 한다. 여기서는 주소번호가 가장 큰 2 사람 만을 변경하도록 예제를 만들었다

USE ADVENTUREWORKSGO

UPDATE PERSON.ADDRESSSET AddressLine2 = 'Daehan Bldg. 3th'FROM (SELECT TOP 2 ADDRESSID AS AID FROM PERSON.ADDRESS

ORDER BY ADDRESSID DESC)AS A

WHERE ADDRESSID = A.AIDGO6. 실행결과를 확인한다

SELECT TOP 10 * FROM ADVENTUREWORKS.PERSON.ADDRESSORDER BY ADDRESSID DESC

Task 3: DELETE 에서 TOP 사용하기

1. DELETE 를 이용해 삭제할 수 있다. 아래 문장을 실행해서 확인한다. 잘 실행된다

BEGIN TRANDELETE TOP (20)

FROM Purchasing.PurchaseOrderDetailWHERE DueDate < '20020701'

2. 작업을 취소한다

ROLLBACK TRAN

Page 13: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

13

Chapter 2 -연습 2: 문자셋 지원

시나리오SQL Server 2005 에서 새롭게 지원하는 KOREA90 문자셋에 대한 개념과 사용법을 알아본다.

Task 1: SQL Server 2000 에서 지원하는 문자셋 살펴보기.

1. 다음 문장을 실행한다. 총 754 개인 것을 확인할 수 있다 . 또한 korea_90 으로 시작하는 형식은 없는 것을 확인할 수 있다

SELECT * FROM ::FN_HELPCOLLATIONS()

Task 2: SQL Server 2005 에서 지원하는 문자셋 살펴보기.

1. 다음 문장을 실행한다. 총 1011 개인 것을 확인할 수 있다. korean_90 형식도 확인할 수 있다

SELECT * FROM FN_HELPCOLLATIONS()

Task 3: korean_90 을 구현하는 방법.

1. 실습을 위한 데이터베이스 준비

CREATE DATABASE TESTGOUSE TESTGO

2. 테이블을 생성하되, 문자 컬럼을 일반 유니코드형식으로 작성한다

CREATE TABLE DBO.KOR (KID INT, KNAME VARCHAR(50) COLLATE KOREAN_WANSUNG_CI_AS)GO

3. 생성한 테이블의 문자열에 한글고어문자를 입력하고, 결과를 확인한다. 정확한 데이터가 입력되어 있지 않은 것을 확인할 수 있다

INSERT INTO DBO.KOR(KID,KNAME)VALUES(1, 'ᆟ')

GOSELECT * FROM KORSELECT UNICODE(KNAME) FROM DBO.KOR

Page 14: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

14

4. 이번에는 테이블을 생성하되, 문자 컬럼을 KOREAN_90_CI_AS 형식으로 작성한다

CREATE TABLE DBO.KOR2 (KID INT, KNAME NVARCHAR(50) COLLATE KOREAN_90_CI_AS )GO

5. 생성한 테이블의 문자열에 한글고어문자를 입력하고, 결과를 확인한다. 정확한 데이터가 입력되어 있는 것을 확인할 수 있다

INSERT INTO DBO.KOR2(KID,KNAME)VALUES(1, CAST(N'ᆟ' AS NVARCHAR(50)) COLLATE KOREAN_90_CI_AS)

GOSELECT KID, CAST(KNAME AS NVARCHAR(50)) COLLATE KOREAN_90_CI_AS FROM DBO.KOR2SELECT UNICODE(KNAME) FROM DBO.KOR2

6. 컬럼 생성과 입력, 출력 시 모두 KOREAN_90_CI_AS 형식을 설정하지 않으면, 표현이 불가능하다. 이를 조합해서 실습해보자...

--자체실습...

Page 15: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

15

Chapter 2 -연습 3: 파티션(분할) 테이블 구성 및 성능테스트

시나리오SQL Server 2005 에서 지원하는 파티션테이블에 대한 개념과 사용법을 알아본다.

Task 1: 실습을 위한 데이터베이스 준비.

1. 4 개의 추가 데이터파일과 각각의 파일이 포함되는 파일그룹으로 구성되도록 데이터베이스를 생성한다

CREATE DATABASE PARTITIONTESTGO

ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG1GOALTER DATABASE PARTITIONTEST ADD FILEGROUP FG2 GOALTER DATABASE PARTITIONTEST ADD FILEGROUP FG3GOALTER DATABASE PARTITIONTEST ADD FILEGROUP FG4GOALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE11',FILENAME='C:\C\FILE11.NDF',SIZE=10) TO FILEGROUP FG1GOALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE22',FILENAME='C:\D\FILE22.NDF',SIZE=10) TO FILEGROUP FG2GOALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE33',FILENAME='C:\E\FILE33.NDF',SIZE=10) TO FILEGROUP FG3GOALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE44',FILENAME='C:\F\FILE44.NDF',SIZE=10) TO FILEGROUP FG4GO

Task 2: 파티션구성, 파티션함수생성->파티션스킴생성->테이블생성.

Page 16: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

16

1. 날짜를 기준으로 4 부분으로 분할 입력하게 해 주는, 파티션함수(function)를 생성한다

USE PARTITIONTESTGO

CREATE PARTITION FUNCTION DBO.DateFn(smalldatetime)AS RANGE RIGHT FOR VALUES ('20000101', '20030101','20060101') -- 오

른쪽값을기준값으로줌GO

2. 생성한 함수의 날짜범위에 파일그룹이 할당되도록, 파티션스킴(scheme)을 작성한다

CREATE PARTITION SCHEME DBO.DateSchemeAS PARTITION DateFn TO (fg1,fg2,fg3,fg4)

GO

Task 3: 파티션이 구성되었으므로, 이 파티션에 데이터가 분할되어 저장되도록, 테이블을 작성하고 데이터를 입력한다.

1. 테이블을 생성한다. 이 때 ApprDate 컬럼이 분할의 기준이 되도록, Partition scheme(파티션구성표)에 매핑한다

CREATE TABLE DBO.CardAppr(Cid int identity, ApprDate smalldatetime)ON DateScheme(ApprDate)

GO

2. 테스트를 할 수 있도록, 데이터를 적절히 입력한다

SET NOCOUNT ON

DECLARE @NO INTSET @NO=0WHILE @NO < 1000BEGIN

INSERT INTO DBO.CardAppr VALUES ( convert(smalldatetime,'20000101') + (@no*4+0))

INSERT INTO DBO.CardAppr VALUES ( convert(smalldatetime,'20000101') + (@no*4+1))

INSERT INTO DBO.CardAppr VALUES ( convert(smalldatetime,'20000101') + (@no*4+2))

INSERT INTO DBO.CardAppr VALUES ( convert(smalldatetime,'20000101') + (@no*4+3))

SET @NO=@NO+1ENDSET NOCOUNT ONGO

3. 입력된 데이터를 확인한다

SELECT COUNT(*) FROM DBO.CardApprSELECT max(apprdate) FROM DBO.CardApprSELECT * FROM DBO.CardAppr order by cid

4. 파티션 범위를 확인한다

SELECT $partition.DateFn(ApprDate) AS 파티션번호, min(ApprDate) AS MinDate, max(ApprDate) AS MaxDate

Page 17: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

17

, count(*) FROM dbo.CardAppr GROUP BY $partition.DateFn(ApprDate)ORDER BY 파티션번호

GO--> 파티션1번이비어있음SELECT * FROM CardAppr

WHERE $PARTITION.DateFn(ApprDate) = 1

5. 파티션 정보를 확인한다

SELECT OBJECT_NAME(object_id) AS ObjectName, * FROM sys.partitionsWHERE object_id = OBJECT_ID('CardAppr') ORDER BY partition_number, index_id

GO

Task 4: 실제로 특정날짜만을 질의하는 쿼리를 실행했을 때, 해당파티션만을 검색하는지 확인한다.

1. 인덱스를 생성한다.

CREATE clustered INDEX ix_CardAppr_ApprDate ON DBO.CardAppr (ApprDate, cid)ON DateScheme(ApprDate)

GO

2. 실행계획을 확인한다. StmtText 열의 끝부분을 확인하면 된다

SET STATISTICS PROFILE ONGOSELECT * FROM DBO.CardAppr WHERE ApprDate ='20030101'SET STATISTICS PROFILE OFF

Page 18: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

18

Chapter 3 -연습 1: DDL 트리거를 이용한 로깅 및 테이블 변경 방지

시나리오SQL Server 2005 에서 지원하는 DDL Trigger 에 대한 개념과 사용법을 알아본다.

Task 1: 테이블생성내역을 XML 형식으로남기기.

1. 기록을 로깅할 테이블을 작성한다

CREATE TABLE DBO.DDLLOG( DATA XML )GO

2. 기록을 남기는 작업을 포함하는 DDL 트리거를 작성한다

CREATE TRIGGER TRG_CREATETABON DATABASE FOR CREATE_TABLE

ASINSERT INTO DBO.DDLLOG VALUES( EVENTDATA())--DDL 트리거를실행하는이벤트에대한정보는EVENTDATA 함수를사용하여캡처할수있다--이함수는XML 값을반환한다

GO

3. 실제로 테이블을 생성해 본다

CREATE TABLE DBO.SSS( SID INT PRIMARY KEY IDENTITY, SNAME VARCHAR(MAX))GO

4. 로깅이 잘 되어 있는 지 확인한다. 결과값(XML)을 클릭하면 XML 데이터를 확인할 수 있다. 어떤 정보가 있는 지 확인해 본다

SELECT * FROM DBO.DDLLOG

Task 2: 테이블 생성내역을 문자열기록으로 남기기.

Page 19: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

19

1. 기록을 남기는 작업을 포함하는 DDL 트리거를 작성한다

CREATE TRIGGER TRG_CREATETAB2ON DATABASE FOR CREATE_TABLE

AS--value 와CommandText 등메소드는대소문자구별을한다. 유의할것SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)

[1]','nvarchar(max)')GO

2. 실제로 테이블을 생성해 본다. 실행하자마자 트리거가 발생되어, 사용자가 실행한 DDL 문을 확인할 수 있다

CREATE TABLE DBO.TTT3( TID INT )GO

-- 결과 ‘CREATE TABLE TTT4( TID INT )’

Task 3: 특정 테이블에 대한 삭제작업을 금지시키기.

1. 삭제대상이 될 테이블을 작성한다

CREATE TABLE DBO.ZZZ(ZID INT, ZNAME VARCHAR(10))GO

2. DROP_TABLE 이벤트에 대하여, 'ZZZ' 테이블이라면 롤백하는 DDL 트리거를 작성한다

CREATE TRIGGER TRG_PREVENT_DROPTTTON DATABASE FOR DROP_TABLE

ASDECLARE @TAB TABLE( TNAME VARCHAR(MAX))INSERT @TABSELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)

[1]','NVARCHAR(MAX)')-- SELECT * FROM @TABIF EXISTS(SELECT * FROM @TAB WHERE TNAME LIKE '%ZZZ%')BEGIN

ROLLBACKEND

GO

3. DROP TABLE 문장을 각각 조건에 없는 테이블(SSS)와, 조건에 해당하는 테이블(ZZZ)에 대하여 실행한다

DROP TABLE DBO.SSS --> 트리거발생되지않음GODROP TABLE DBO.ZZZ --> 트리거발생됨GO

4. ROLLBACK 처리가 되었는지 확인한다

SELECT * FROM DBO.SSS --> 삭제됨SELECT * FROM DBO.ZZZ --> 롤백되어삭제되지않았음

5. 데이터베이스 수준의 DDL 트리거를 삭제하는 방법은 다음과 같다

DROP TRIGGER TRG_PREVENT_DROPTTT ON DATABASE

Page 20: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

20

GO

Chapter 3 -연습 2: DDL 트리거를 이용한 MASTER DATABASE 백업자동화

시나리오1. 사용자정의 메시지를 생성한다.

2. master 데이터베이스에 변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다.

3. master 데이터베이스를 백업하는 job 을 생성한다.

4. 메시지이벤트가 발생되면 자동으로 백업 job 을 수행하도록, 경고를 작성한다.

5. 실제로 master 데이터베이스 변경작업을 시도하여, 백업이 되는지 확인한다.

Task 1: 사용자정의 메시지를 생성한다.

1. master 데이터베이스에서 작업한다

Use MasterGO

2. 아래명령을 실행하여 메시지를 생성한다. 반드시 영문 먼저 생성해야, 한글메시지도 작성된다는 것에 유의하자

EXEC sp_addmessage 50001, 10, N'Master Database has changed' , 'us_english', 'TRUE', 'REPLACE'GOEXEC sp_addmessage 50001, 10, N'마스터데이터베이스내용이변경되었습니다' , 'korean', 'TRUE', 'REPLACE'GO

Task 2: master 데이터베이스에 변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다.

1. 트리거 작성

Page 21: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

21

Create trigger Trg_Master_BackupAutomation_Serveron all SERVER for

CREATE_DATABASE , ALTER_DATABASE, DROP_DATABASE , DDL_LOGIN_EVENTS, DDL_GDR_SERVER_EVENTS, DDL_AUTHORIZATION_SERVER_EVENTS , DDL_ENDPOINT_EVENTSas

Raiserror (50001, 10, 1) with logGO

Task 3: master 데이터베이스를 백업하는 job 을 생성한다.

1. AGENT 서비스가 시작이 되어 있지 않다면, '관리도구/서비스'에서 'SQL Server Agent' 서비스를 시작하도록 한다

2. "SSMS/개체탐색기/SQL Server 에이전트/작업"에서 오른쪽 버튼을 눌러, “새 작업” 메뉴를 클릭한다. 창이 열리면 다음을 실행한다

a. “일반/이름” 항목에 “Master 데이터베이스백업” 을 입력한다.

b. “일반/범주” 항목에서 “데이터베이스유지관리” 를 선택한다.

c. “단계/새로만들기” 버튼을 클릭한다.

i. 새로운 창의“일반/단계” 이름에 “Master 데이터베이스백업” 을 입력한다.

ii. “일반/유형” 에는 “Transact-SQL 스크립트(T-SQL)” 을 선택한다.

iii. “다음계정으로실행” 항목은 초기값을 사용한다.

iv. “데이터베이스” 항목은 master 로 선택한다.

v. “명령” 항목에는 다음 값을 입력한다.

Backup database master To disk='D:\TSQL\Master.bak' with Init, Format

GO

vi. “구문분석” 버튼을 누른다. 이때 오류가 없어야 한다.

vii. “고급/성공한경우동작” 항목은 “성공보고와함께작업종료” 를 선택한다.

viii. “확인” 버튼을 누른다.

d. “확인” 버튼을 누른다.

Task 4: 메시지이벤트가 발생되면 자동으로 백업 job 을 수행하도록, 경고를 작성한다.

1. SSMS 의 개체탐색기의 “SQL Server 에이전트/경고” 항목에서 마우스 오른쪽버튼을 클릭하고, “새경고” 버튼을 누른다. 창이 열리면 다음을 실행한다

a. “일반/이름” 항목에 “Master 데이터베이스백업자동화”를 입력한다.

b. “일반/유형” 항목에서 “SQL Server 이벤트경고” 를 선택한다.

c. “일반/데이터베이스이름” 항목에서 “Master” 를 선택한다.

d. “일반/경고발생기준” 항목은 “오류번호” 옵션을 선택하고, “50001”을 입력한다.

e. “응답/작업실행” 체크박스에 체크표시한다.

f. “응답/작업실행”의 목록에서, 사전에 작업을 생성해 둔, “Master 데이터베이스백업”을 선택한다.

Page 22: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

22

g. “확인” 버튼을 누른다.

Task 5: 실제로 master 데이터베이스변경작업을시도하여, 백업이되는지확인한다

1. 다음 작업들을 실행해서, 실제로 Master 데이터베이스에 대한 자동백업이 수행되는지 확인한다

a. SSMS 의 쿼리실행창에서 다음 명령을 수행하고, 탐색기의 ‘D:\TSQL\” 폴더 내에 “Master.bak” 가 생성되었는지 각각의 명령에 대해 확인한다.

CREATE DATABASE TRGGODROP DATABASE TRGGO

b. 역시 다음 명령을 실행하고, 탐색기의 ‘D:\TSQL\” 폴더 내에 “Master.bak” 가 생성되었는지 각각의 명령에 대해 확인한다.

CREATE LOGIN AAA WITH PASSWORD = 'Pa$$w0rd' GODROP LOGIN AAA GO

2. 서버 수준의 DDL 트리거를 삭제하는 방법은 다음과 같다

DROP TRIGGER Trg_Master_BackupAutomation_Server on all SERVER

GO

Page 23: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

23

Chapter 3 -연습 3: XML 향상

시나리오SQL Server 2005 에서 새롭게 지원하는 XML 사용법을 알아본다.

Task 1: XML 형식으로 데이터를 출력하여, 응용프로그램으로 반환할 수 있다.

1. 기존에 저장되어 있는 NON XML 컬럼을 XML 로 출력 가능함. 이때 자동으로 타입변경가능

USE ADVENTUREWORKSGO

SELECT ContactID, FirstName, LastName, PhoneFROM Person.ContactORDER BY ContactIDFOR XML AUTO, TYPE

Task 2: 출력(SELECT) 뿐 아니라, 입력과 수정에도 사용 가능하다는 것을 확인한다.

1. XML 형식을 갖는 컬럼을 포함하여 테이블을 생성하고 데이터를 입력한다

CREATE TABLE DBO.T1(intCol int, XmlCol xml)GOINSERT INTO DBO.T1 VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')GO2. XML 형식 컬럼을 조회해서, 다른 테이블의 XML 컬럼에 입력 가능하다

CREATE TABLE DBO.T2(XmlCol xml)GOINSERT INTO DBO.T2(XmlCol) SELECT (SELECT XmlCol.query('/Root') FROM DBO.T1 FOR XML AUTO,TYPE) GO

3. 결과를 확인한다

SELECT * FROM DBO.T2

Page 24: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

24

Chapter 4 -연습 1: RANKING 함수들을 이용해서, 쉽게 순위 구하기

시나리오SQL Server 2005 에서 새롭게 지원하는 순위함수들의 의미와 사용법을 알아본다.

Task 1: RANK() 함수 기능이해

1. 아래 문장을 실행해서 RANK() 함수의 기본기능을 이해한다. 결과를 보면 ListPrice 값이 4.99 인 예에서 동점도 랭킹에 포함되고 있음을 알 수 있다

USE ADVENTUREWORKSGO

SELECT P.Name Product, P.ListPrice, PSC.Name Category, RANK() OVER(ORDER BY P.ListPrice ) AS PriceRankFROM Production.Product P JOIN Production.ProductSubCategory PSCON P.ProductSubCategoryID = PSC.ProductSubCategoryIDORDER BY 2, 4

2. 아래 문장을 실행해서 PARTITION BY 키워드를 사용했을 때의 기능을 이해한다. 결과를 보면 Category 값이 Gloves, handlesbars 인 예에서 동점도 랭킹에 포함되고 있음을 알 수 있다

SELECT P.Name Product, P.ListPrice, PSC.Name Category, RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRankFROM Production.Product P JOIN Production.ProductSubCategory PSCON P.ProductSubCategoryID = PSC.ProductSubCategoryIDORDER BY 3, 4

Task 2: DENSE_RANK () 함수 기능이해

1. 아래 문장을 실행해서 DENSE_RANK() 함수의 기능을 이해한다. 결과를 보면 Category 값이 Gloves, handlesbars 인 예에서 동점과 상관없이 점수 자체로만 랭킹하고 있음을 알 수 있다

SELECT P.Name Product, P.ListPrice, PSC.Name Category,

Page 25: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

25

DENSE_RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRank

FROM Production.Product P JOIN Production.ProductSubCategory PSCON P.ProductSubCategoryID = PSC.ProductSubCategoryIDORDER BY 3,4

Task 3: ROW_NUMBER () 함수 기능이해

1. 아래 문장을 실행해서 ROW_NUMBER() 함수의 기능을 이해한다. 결과를 보면 Category 값이 Gloves, handlesbars 인 예에서 동점과 상관없이 행으로, 즉 건수로만 랭킹하고 있음을 알 수 있다. 이때 카테고리와 가격이 모두 같은 데이터에 대해서는, 사용자가 3 차 이상의 정렬을 지정해야 순위가 의미 있어진다

SELECT ROW_NUMBER() OVER(PARTITION BY PC.Name ORDER BY ListPrice) AS Row, PC.Name Category, P.Name Product, P.ListPriceFROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN

Production.ProductCategory PCON PSC.ProductCategoryID = PC.ProductCategoryIDORDER BY 2,1

Task 4: NTILE () 함수 기능이해

1. 아래 문장을 실행해서 ROW_NUMBER() 함수의 기능을 이해한다. 결과를 보면 각 Category 값에 대해 가격대를 3 부분으로 대략 나누어 출력해 주고 있음을 알 수 있다

SELECT NTILE(3) OVER(PARTITION BY PC.Name ORDER BY ListPrice) AS PriceBand, PC.Name Category, P.Name Product, P.ListPriceFROM Production.Product P JOIN Production.ProductSubCategory PSCON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN

Production.ProductCategory PC ON PSC.ProductCategoryID = PC.ProductCategoryIDORDER BY 2,4

Page 26: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

26

Chapter 4 -연습 2: PIVOT & UNPIVOT

시나리오SQL Server 2005 에서 새롭게 지원하는 PIVOT, UNPIVOT 연산자에 대한 의미와 사용법을 알아본다.

Task 1: PIVOT 이해

1. 2000 인경우의 설계방법은 다음과 같다

CREATE TABLE MEMBER1 (MID INT IDENTITY PRIMARY KEY, MNAME NVARCHAR(50), 사과CHAR(1), 사진CHAR(1), 음악CHAR(1), 영화CHAR(1), 뮤지컬CHAR(1))

GOINSERT INTO MEMBER1(MNAME,사과,사진,음악,영화,뮤지컬)

VALUES(N'홍길동','1','0','0','0','1')INSERT INTO MEMBER1(MNAME,사과,사진,음악,영화,뮤지컬)

VALUES(N'홍길동','0','1','1','1','0')INSERT INTO MEMBER1(MNAME,사과,사진,음악,영화,뮤지컬)

VALUES(N'이순신','1','1','1','0','0')GO2. 2005 에서의 설계-->설계단순화 및 저장공간 감소

CREATE TABLE MEMBER2 (MID INT IDENTITY PRIMARY KEY, MNAME NVARCHAR(50), FAVORITE NVARCHAR(20))GOINSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'사과')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'사진')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'사진')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'사진')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'사진')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'음악')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'홍길동', N'음악')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'음악')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'영화')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'영화')INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'뮤지컬')GO

3. 관심분야종류를 파악한다

SELECT DISTINCT FAVORITE FROM DBO.MEMBER2

4. 필요한 관심분야 종류별로 회원 별 개수를 출력한다

Page 27: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

27

SELECT * FROM DBO.MEMBER2PIVOT (COUNT(MID) FOR FAVORITE IN ([사진],[음악],[영화],[뮤지컬])) AS PVT

Chapter 4 -연습 3: 시스템 정보 보기

시나리오SQL Server 2005 에서 추가로 지원하는 시스템정보(메타데이터) 추출 방법인 DMV 에 대해 종류와 의미를 알아본다.

Task 1: 일반적으로 사용되는 카탈로그뷰를 사용해 본다

1. 다음을 실행하면 데이터베이스 내의 모든 개체정보를 볼 수 있다

SELECT * FROM SYS.OBJECTS 2. 다음을 실행하면 인스턴스에 포함된 모든 데이터베이스정보를 볼 수 있다

SELECT * FROM SYS.DATABASES3. 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다

SELECT * FROM SYS.TABLES ORDER BY NAME4. 도움말의 색인항목의 찾을 대상 textbox 에서 "SYS."을 입력한 후 나타나는 카탈로그뷰의 목록을

확인한다

Task 2: 일반적으로 사용할 수 있는 정보스키마뷰를 사용해 본다

1. 다음을 실행하면 데이터베이스 내의 모든 테이블과 뷰정보를 볼 수 있다

SELECT * FROM INFORMATION_SCHEMA.TABLES2. 다음을 실행하면 WHERE 절에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다

SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'ADDRESS'3. 도움말의 색인항목의 찾을대상 textbox 에서 "INFORMATION_" 을 입력한 후 나타나는 카탈로그뷰의

목록을 확인한다

Task 3: 일반적으로 사용되는 호환성뷰를 사용해본다

1. 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다. SYS.OBJECTS 와 비교해보자. ID컬럼명 등이 다르고 출력하는 속성목록이 다른 것을 확인할 수 있다

SELECT * FROM SYSOBJECTS2. 다음을 실행하면 현재 실행계획캐쉬에 저장되어 있는 명령들을 확인할 수 있다

SELECT * FROM SYS.SYSCACHEOBJECTS3. 다음을 실행하면 WHERE 절 에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다

Page 28: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

28

SELECT * FROM SYSCOLUMNS WHERE ID = OBJECT_ID('PERSON.ADDRESS')4. 도움말의 주소창에 다음을 입력하여 출력되는, 이전 시스템테이블과 2005 시스템뷰 와의 매핑관계를

확인한다

ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.ko/tsqlref9/html/a616fce9-b4c1-49da-87a7-9d6f74911d8f.htm

Task 4: 일반적으로 사용할 수 있는 메타데이터함수를 사용해본다

1. 다음을 실행하면 WHERE절 에서 지정한 테이블들의 컬럼정보를 확인할 수 있다

SELECT OBJECT_NAME(ID), NAME, TYPE_NAME(XTYPE), LENGTH FROM SYSCOLUMNS WHERE ID = OBJECT_ID('PERSON.ADDRESS') ORDER BY COLID

2. 다음을 실행해서 어떤 정보들을 볼 수 있는지 확인한다

SELECT DB_ID('MASTER') AS 데이터베이스ID , DB_NAME(7) AS 데이터베이스명, OBJECT_ID('PERSON.ADDRESS') AS 개체ID, @@VERSION

, DATABASEPROPERTYEX('ADVENTUREWORKS','RECOVERY') AS 현재복구모델유형, OBJECTPROPERTY(OBJECT_ID('PERSON.ADDRESS'),'ISINDEXED') AS 테이블의인덱스존재여부3. 도움말의 주소창에 다음을 입력하여 출력되는 메타데이터함수의 목록을 확인한다

ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.ko/tsqlref9/html/a18c12a9-59ad-4711-a862-39d8f28476b0.htm

Task 5: 일반적으로 사용할 수 있는 시스템프로시저를 사용해본다

1. 다음을 실행하면 현재 인스턴스의 DB 버전과 OS 버전 등을 확인할 수 있다

EXEC DBO.XP_MSVER2. 다음을 실행하면 지정한 테이블의 제약정보를 확인할 수 있다

EXEC DBO.SP_HELPCONSTRAINT 'PERSON.ADDRESS'3. 다음을 실행하면 지정한 테이블의 컬럼정보를 확인할 수 있다

EXEC DBO.SP_COLUMNS 'ADDRESS', 'PERSON'

Page 29: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

29

Chapter 4 -연습 4: DMV

시나리오SQL Server 2005 에서 추가로 지원하는 시스템정보(메타데이터) 추출 방법인 DMV 에 대해 종류와 의미를 알아본다.

Task 1: 실습준비

1. 아래 문장을 10 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다

SELECT * FROM Sales.SalesOrderDetailSELECT * FROM Sales.Individual2. --2. 아래 문장을 50 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다

SELECT * FROM PRODUCTION.CULTURE

Task 2: sys.dm_exec_query_stats 동적뷰를 질의하여, 리소스를 많이 차지하고 있는 상위쿼리를 확인한다

1. sys.dm_exec_query_stats 의 기본정보를 확인한다.

SELECT * FROM SYS.dm_exec_query_stats2. 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_exec_query_stats" 을 입력하여, 이 뷰의 속성정보를

확인한다. total_worker_time,execution_count, total_physical_reads, last_physical_reads 등을 특히 확인한다

3. CPU 점유시간 별 상위쿼리를 확인하기 위해 다음을 실행한다. 이때 실제 실행된 문장은 sql_handle 컬럼에 바이너리로 저장되어 있으므로, 이를 문자열로 출력하기 위해 동적 관리 함수인 dm_exec_sql_text 를 사용한다

SELECT TOP 30 total_worker_time/execution_count AS [CPU점유시간], SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS [실행한명령문]

FROM sys.dm_exec_query_stats AS qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS stORDER BY total_worker_time/execution_count DESC

4. 실행횟수 별 상위쿼리를 확인하기 위해 다음을 실행한다. 역시 마찬가지로 dm_exec_sql_text 함수를 이용한다

SELECT TOP 30 EXECUTION_count AS [명령문실행횟수], SUBSTRING(st.text, (qs.statement_start_offset/2)+1,

Page 30: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

30

((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS [실행한명령문]

FROM sys.dm_exec_query_stats AS qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS stORDER BY EXECUTION_count DESC

5. 읽기수 별 상위쿼리를 확인하기 위해 다음을 실행한다. 역시 마찬가지로 dm_exec_sql_text 함수를 이용한다

SELECT TOP 30 last_logical_reads AS [페이지읽기수], SUBSTRING(st.text, (qs.statement_start_offset/2)+1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS [실행한명령문]

FROM sys.dm_exec_query_stats AS qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS stORDER BY last_logical_reads DESC

Task 3: sys.dm_exec_cached_plans 동적뷰를 질의하여, 캐시된 플랜정보를 확인한다

1. sys.dm_exec_cached_plans 의 기본정보를 확인한다.

SELECT * FROM SYS.dm_exec_cached_plans2. 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_exec_cached_plans" 을 입력하여, 이 뷰의

속성정보를 확인한다.

SELECT * FROM sys.dm_exec_cached_plans 3. 캐쉬된 플랜에 대한 사용횟수 별 상위 100 개의 쿼리를 확인한다. 상위문장을 확인한다

SELECT TOP 100 usecounts, refcounts, cacheobjtype, objtype, st.text AS [실행한명령문]FROM sys.dm_exec_cached_plans AS cpCROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS stORDER BY usecounts DESC, refcounts DESC

4. 캐쉬된 플랜에 대한 메모리점유량 별 상위 100 개의 쿼리를 확인한다. 상위문장을 확인한다

SELECT TOP 100 st.text AS [명령문], ecp.memory_object_address AS [메모리주소] , pages_allocated_count AS [점유페이지수], pages_allocated_count*8192 AS [점유메모리량(bytes)], type AS [컴파일유형]

FROM sys.dm_exec_cached_plans AS ecp JOIN sys.dm_os_memory_objects AS omo

ON ecp.memory_object_address = omo.memory_object_address OR ecp.memory_object_address = omo.parent_address

CROSS APPLY sys.dm_exec_sql_text(ecp.plan_handle) AS stWHERE cacheobjtype = 'Compiled Plan' AND st.text not like '%sys%'ORDER BY 3 DESC, 5 DESC

GO5. 아래를 각각 따로따로 여러번(5 번정도) 실행한 뒤, 위 4 번 문장을 다시한번 실행해본다. WHERE 을

사용하지 않은 명령은 인덱스를 사용하지 못했으므로 50 PAGE, 사용한 명령은 인덱스를 사용했으므로 2 PAGE 만을 점유하고 있는 것을 알 수 있다

SELECT * FROM SALES.INDIVIDUAL SELECT * FROM SALES.INDIVIDUAL WHERE CUSTOMERID = 11000

Page 31: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

31

Task 4: sys.dm_tran_database_transactions 동적뷰를 질의하여, 의미있는 트랜잭션 중에서 로그생성수 기준 상위 트랜잭션을 확인한다

1. sys.dm_tran_database_transactions 의기본정보를확인한다.

SELECT * FROM SYS.dm_tran_database_transactions2. 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_tran_database_transactions" 을 입력하여, 이 뷰의

속성정보를 확인한다.

3. 각기 다른 3 개의 쿼리실행창을 열어서 각각 다음 문장을 실행한다. 각각의 창은 SESSION1, SESSION2, SESSION3 으로 명명한다.

--SESSION1)USE ADVENTUREWORKSGOBEGIN TRAN

UPDATE PERSON.ADDRESSSET ADDRESSLINE2 = 'SEOUL'

--SESSION2)USE ADVENTUREWORKSGOBEGIN TRAN

UPDATE SALES.INDIVIDUALSET CONTACTID = '11101'

--SESSION3)USE ADVENTUREWORKSGOBEGIN TRAN

UPDATE Sales.CustomerSET MODIFIEDDATE = GETDATE()

4. 현재 서버의 트랜잭션정보를, 아래 명령을 실행해서 확인한다

USE MASTERGOSELECT TRANSACTION_ID, DB_NAME(DATABASE_ID) AS DB명, DATABASE_TRANSACTION_BEGIN_TIME

, CASE DATABASE_TRANSACTION_TYPE WHEN 1 THEN '읽기/쓰기' WHEN 2 THEN '읽기전용' WHEN 3 THEN '시스템' END AS [일기/쓰기]

, CASE database_transaction_state WHEN 1 THEN '미초기화' WHEN 2 THEN '초기화됨,로그쓰기전' WHEN 3 THEN '로그쓰임' WHEN 4 THEN '트랜잭션진행중' WHEN 5 THEN '커밋됨' WHEN 6 THEN '롤백됨' WHEN 7 THEN '커밋중' END AS [트랜잭션상태]

, database_transaction_log_record_count [생성된로그행수] FROM sys.dm_tran_database_transactionsWHERE DATABASE_TRANSACTION_BEGIN_TIME IS NOT NULL ORDER BY [생성된로그행수] DESC

Task 5: TEMPDB 사용량이 많은 연결정보를 확인한다

1. TEMPDB 에 할당된 페이지크기 별 상위세션 출력하기

SELECT SESSION_ID, INTERNAL_OBJECTS_ALLOC_PAGE_COUNT, INTERNAL_OBJECTS_DEALLOC_PAGE_COUNT FROM SYS.DM_DB_SESSION_SPACE_USAGE ORDER BY INTERNAL_OBJECTS_ALLOC_PAGE_COUNT DESC

Page 32: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

32

2. 인스턴스명에서 오른쪽버튼을 클릭하고, "보고서/표준보고서/상위세션" 메뉴를 눌러서 읽기,쓰기항목의 세션의 SPID 를 확인한다. 이는 메모리 사용량순위이지만 TEMPDB 사용량과도 어느 정도 일맥상통하는 것을 확인할 수 있다

Chapter 5 -연습 1: 원격쿼리 향상

시나리오SQL Server 2005 에서 향상된 원격쿼리의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다.

Task 1: EXECUTE .. AT 을 이용하여 쿼리하기

1. 먼저 원격서버를 등록한다. 만일 원격서버대상이 없는 경우에는 로컬서버에 있는 인스턴스를 등록하도록 한다

a. 만일 로컬서버의 인스턴스명을 모르는 경우, 다음 명령을 실행해서 확인할 수 있다

SELECT * FROM SYS.SERVERSb. 만일 로컬서버의 인스턴스명을 확인했다면 다음을 실행하면 된다

EXEC master.dbo.sp_addlinkedserver @server = N'CEYX2' --> 'CEYX2' 가 원격서버명이다. 이 부분을 변경한다., @srvproduct=N'SQLServer', @provider=N'SQLNCLI', @datasrc=N'CEYX' --> 'CEYX' 가 로컬서버명이다. 이 부분을 변경한다.GO

2. 쿼리에 대한 실행계획과 IO 정보를 출력하기 위해 다음 두 옵션을설정한다

SET STATISTICS PROFILE ON --> 실행계획출력SET STATISTICS IO ON --> IO통계출력3. 아래의 3개의 쿼리를 비교한다.

a. 일반적으로 사용하는 원격쿼리. 실행계획을 로컬서버가 생성하고 로컬에서 실행한다SELECT * FROM CEYX2.NORTHWIND.DBO.EMPLOYEES

WHERE EMPLOYEEID = 1b. 일반적으로 사용하는 통과쿼리. 실행계획을 원격서버가 생성하고 원격에서 실행한다. 그러므로

정확한 실행계획을 출력하지 않는다--> !!!!!!!!! 로컬서버에 대해서는 실행되지 않으므로 위 문장은 실패한다. --> !!!!!!!!! 그러므로 다음 옵션을 설정하고 재실행하도록 한다.SP_SERVEROPTION 'CEYX2', 'DATA ACCESS','TRUE' --> 원격서버에 대해 설정할 옵션, DEFAULT 값은 'FALSE'GO

SELECT * FROM OPENQUERY(CEYX2, 'SELECT * FROM NORTHWIND.DBO.EMPLOYEES WHERE EMPLOYEEID = 1')

c. EXECUTE ... AT.. 을 이용한원격쿼리. 실행계획을 원격서버가 생성하고 원격에서 실행한다. 로컬서버는 데이터만을 받는다. 실행계획을 출력하지 않는다

EXEC sp_serveroption 'CEYX2', 'rpc out', 'true'GOEXECUTE ('SELECT *

FROM NORTHWIND.DBO.EMPLOYEES WHERE EMPLOYEEID = ? ', 1) AT CEYX2

Page 33: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

33

GO

Chapter 5 -연습 2: tablesample

시나리오SQL Server 2005 에서 향상된 원격쿼리의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다.

Task 1: tablesample 성능비교, 개발/유지보수 시 흔히 실행하는 top 과 2005 tablesample 과의 성능비교

1. 데이터베이스 연결을 변경한다. 다음을 실행하면 된다

USE AdventureworksGO2. 다음 두 문장을 실행한다

SELECT * FROM SALES.INDIVIDUAL TABLESAMPLE (100 ROWS)

GOSELECT TOP 100 * FROM SALES.INDIVIDUAL GO3. 2 번 단계의 두 문장을 영역으로 선택하고, SSMS 의 "예상실행계획보기" 단추를 누르거나, Ctrl+L 을 누른다. 이때 출력되는 실행계획을 비교해 본다. 얼마나차이가나는지확인한다

Task 2 : 일정한 결과집합을 샘플링하고 싶다면 repeatable 옵션을 사용해야 한다.

1. 다음을 실행해 보자. 실행할 때마다 다른 결과를 확인할 수 있다

SELECT * FROM SALES.INDIVIDUAL TABLESAMPLE (10 PERCENT)

2. 다음을 실행해 보자. 실행할 때마다 다른 결과(행개수부터다름)를 확인할 수 있다

SELECT * FROM SALES.INDIVIDUAL TABLESAMPLE (1000 ROWS)

3. 다음을 실행해 보자. 매번 실행할 때마다 결과가 동일하다. REPEATABLE 옵션의 숫자는 큰 의미없다

SELECT * FROM SALES.INDIVIDUAL TABLESAMPLE (10 PERCENT) REPEATABLE (10)

Page 34: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

34

Chapter 5 -연습 3: cascade (연계참조 무결성)

시나리오SQL Server 2005 에서 향상된 cascade 의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다.

Task 1: cascade 기본개념

1. 부모테이블과 자식테이블을 생성하고 데이터를 입력한다. 자식테이블 생성 시 cascade 옵션을 지정한다

CREATE TABLE DBO.MOVIE ( MCODE CHAR(4) PRIMARY KEY, MOVIENAME VARCHAR(50))GOINSERT INTO DBO.MOVIE(MCODE,MOVIENAME) VALUES ('A100', 'LUNATIC')INSERT INTO DBO.MOVIE(MCODE,MOVIENAME) VALUES ('B200', '다만널사랑하고있어')GO

CREATE TABLE DBO.ACTOR ( AID INT, ANAME VARCHAR(50), MCODE CHAR(4) DEFAULT 'A100')GOALTER TABLE DBO.ACTOR

ADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES MOVIE(MCODE)

ON UPDATE CASCADE ON DELETE CASCADEGOINSERT INTO DBO.ACTOR VALUES(1,'백재현','A100')INSERT INTO DBO.ACTOR VALUES(2,'나제비','A100')INSERT INTO DBO.ACTOR VALUES(3,'김숙','A100')INSERT INTO DBO.ACTOR VALUES(4,'미야자키아오이','B200')INSERT INTO DBO.ACTOR VALUES(5,'타마키히로시','B200')GO2. 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해 본다. CASCADE 옵션이 설정되어 있지 않았다면

RUNTIME 오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 변경된다

UPDATE DBO.MOVIE SET MCODE = 'H555' WHERE MCODE = 'B200'

GO3. 잘 변경되었는지 확인한다

SELECT * FROM DBO.MOVIESELECT * FROM DBO.ACTOR4. 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. CASCADE 옵션이 설정되어 있지 않았다면 RUNTIME

오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 삭제된다

DELETE FROM DBO.MOVIE WHERE MCODE = 'A100'GO5. 잘 삭제되었는지 확인한다

SELECT * FROM DBO.MOVIESELECT * FROM DBO.ACTOR6. 두 테이블을 모두 삭제한다

DROP TABLE DBO.ACTOR

Page 35: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

35

GODROP TABLE DBO.MOVIEGO

Task 2: cascade 의 SET NULL, SET DEFAULT 옵션이해

1. 위에서 실행했던 task1 의 1 번단계의 스크립트를 한번 더 실행한다. 다만 ALTER 문은 다음 문으로 대체해서 실행하도록 한다

ALTER TABLE DBO.ACTORADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES

MOVIE(MCODE)ON UPDATE SET DEFAULT ON DELETE SET NULL

GO2. 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해본다. 자식테이블값이 동시에 DEFAULT 값인 'A100'

으로 변경된다

UPDATE DBO.MOVIE SET MCODE = 'H555' WHERE MCODE = 'B200'

GO3. 잘 변경되었는지 확인한다

SELECT * FROM DBO.MOVIESELECT * FROM DBO.ACTOR4. 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. 자식테이블값이 동시에 NULL 값으로 변경된다

DELETE FROM DBO.MOVIE WHERE MCODE = 'A100'GO5. 잘 삭제되었는지 확인한다

SELECT * FROM DBO.MOVIESELECT * FROM DBO.ACTOR6. 두 테이블을 모두 삭제한다

DROP TABLE DBO.ACTORGODROP TABLE DBO.MOVIEGO

Page 36: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

36

Chapter 5 -연습 4: OUTPUT

시나리오SQL Server 2005 에서 향상된 cascade 의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다.

Task 1: 삭제정보를 반환하는 OUTPUT

1. 예제를 위한 테이블을 생성한다

CREATE TABLE DBO.OUTPUT_01(OID INT,ONAME VARCHAR(20))GOINSERT INTO DBO.OUTPUT_01 VALUES(1,'AAA')INSERT INTO DBO.OUTPUT_01 VALUES(2,'BBB')INSERT INTO DBO.OUTPUT_01 VALUES(3,'CCC')GO2. 삭제를 실행하되, 삭제된 행을 반환하도록 OUTPUT 절을 설정한다

DELETE DBO.OUTPUT_01 OUTPUT DELETED.*

WHERE OID IN (1,2)GO3. 다음 문장은 SQL Server 2000 에서, OUTPUT 기능을 구현한 예이다

CREATE TRIGGER DBO.TRG_OUTPUT_01ON OUTPUT_01 FOR DELETE

ASSELECT * FROM DELETED

GODROP TRIGGER DBO.TRG_OUTPUT_01GO

Task 2: 수정정보를 기록하도록 OUTPUT 사용

1. 수정정보를 기록할 테이블을 생성한다

CREATE TABLE DBO.OUTPUT_01_History( HID INT IDENTITY, OID INT, BeforeONAME VARCHAR(20), AfterONAME

VARCHAR(20), CHANGEDATE DATETIME )GO2. 수정정보를 기록하도록 UPDATE 구문을 작성한다. 아래는 GO 문 이전까지 한 블록으로 선택해서

실행해야 한다

-- 기록테이블에 정보를 저장할 테이블변수 생성DECLARE @TAB table (OID INT, BeforeONAME VARCHAR(20), AfterONAME VARCHAR(20))-- 수정전 정보와 수정후 정보를 반환하도록 UPDATE...OUTPUT 구문작성. 대상 테이블은 task1 에서 작성한 OUTPUT_01 테이블을 이용한다. 현재 데이터는 1건이 존재한다UPDATE DBO.OUTPUT_01

SET ONAME = 'LEE'

Page 37: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

37

OUTPUT DELETED.OID, DELETED.ONAME, INSERTED.ONAME INTO @TAB

WHERE OID=3-- 테이블변수에 저장된 정보를, 실제 기록테이블에 쓴다INSERT INTO DBO.OUTPUT_01_History(OID,BeforeONAME,AfterONAME,CHANGEDATE)

SELECT OID,BeforeONAME,AfterONAME, GETDATE()FROM @TAB

GO3. 기록테이블에 수정 전후 데이터가 잘 입력되었는지 확인한다

SELECT * FROM DBO.OUTPUT_01_History

Page 38: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

38

Chapter 6 -연습 1: CTE

시나리오SQL Server 2005 에서 추가된 기능인 CTE(Common table expression, 공통테이블식)의 사용방법과 효과를 알아본다.

Task 1: task1) 재귀쿼리작성 시 CTE 를 사용. 아래는 매니저 별 하위직원수를 출력한다. 그러나 계층 구조의 모든 하위직원이 아닌, 바로 한 단계 하위직원수 만을 출력한다. 계층구조를 적용하려면anchor+member 구조를 적용해야 한다.

1. 먼저 일반적인 재귀쿼리문장을 실행한다. 그리고 실행계획을 확인한다(Ctrl+L)

SELECT B.LoginID, count(*) 하위직원수FROM HumanResources.Employee A join HumanResources.Employee BON A.managerid = B.employeeidGROUP BY B.LoginIDORDER BY B.LoginID

2. CTE 를 사용한 쿼리문장을 실행한다. 그리고 실행계획을 확인한다. 직접 작성한 재귀쿼리와 차이가 있는가 (없다)

WITH CTETable(ManagerID) AS (

SELECT ManagerID FROM HumanResources.Employee AS e WHERE ManagerID IS NOT NULL

)SELECT B.LoginID, count(*)

FROM CTETable JOIN HumanResources.Employee BON B.EmployeeID = CTETable.ManagerID

GROUP BY LoginIDORDER BY B.LoginID

GO

Task 2: 테이블변수를 이용하여 재실행

1. 테이블변수를 사용하여 실행한다. 역시 실행계획을 살펴본다. 차이가 있는가 (테이블변수를 사용한 것이 느리다)

DECLARE @TAB TABLE(ManagerID INT)INSERT @TAB SELECT ManagerID FROM HumanResources.Employee AS e WHERE ManagerID IS NOT NULLSELECT B.LoginID, count(*)

FROM @TAB A JOIN HumanResources.Employee BON B.EmployeeID = A.ManagerID

GROUP BY LoginID

Page 39: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

39

ORDER BY B.LoginID

Task 3: 상관관계 하위쿼리구현방법과 CTE 구현방법과의 성능비교, 역시 실행계획을 비교해본다 (성능은 동일하다)

1. 상관관계 하위쿼리로 작성

SELECT * FROM Sales.SalesOrderDetail AWHERE UNITPRICE > (SELECT AVG(UNITPRICE) FROM Sales.SalesOrderDetail B

WHERE A.PRODUCTID=B.PRODUCTID)2. CTE 를 이용해서 작성

WITH CTETable(PRODUCTID, AVGPRICE) AS (

SELECT PRODUCTID, AVG(UNITPRICE)FROM Sales.SalesOrderDetailGROUP BY PRODUCTID)

SELECT * FROM Sales.SalesOrderDetail AWHERE UNITPRICE > (SELECT AVGPRICE FROM CTETable B WHERE

A.PRODUCTID=B.PRODUCTID)

Task 4: 재귀관계가 있는 테이블에 대해, 어떻게 그 하위(부품)정보를 출력하는지에 대한 예를 보여준다

1. 테스트용 테이블을 생성하고, 데이터를 입력한다

CREATE TABLE DBO.CarParts ( CarID int NOT NULL, Part varchar(15), SubPart varchar(15), Qty int)GOINSERT DBO.CarParts VALUES (1, 'Body', 'Door', 4)INSERT DBO.CarParts VALUES (1, 'Body', 'Trunk Lid', 1)INSERT DBO.CarParts VALUES (1, 'Body', 'Car Hood', 1)INSERT DBO.CarParts VALUES (1, 'Door', 'Handle', 1)INSERT DBO.CarParts VALUES (1, 'Door', 'Lock', 1)INSERT DBO.CarParts VALUES (1, 'Door', 'Window', 1)INSERT DBO.CarParts VALUES (1, 'Body', 'Rivets', 1000)INSERT DBO.CarParts VALUES (1, 'Door', 'Rivets', 100)INSERT DBO.CarParts VALUES (1, 'Door', 'Mirror', 1)GO2. CTE 를 이용해서 좀 더 단순하게 부품별 하위부품개수를 출력한다

WITH CarPartsCTE(SubPart, Qty)AS(-- 기준테이블(anchor member)SELECT SubPart, Qty

FROM DBO.CarPartsWHERE Part = 'Body'

UNION ALL-- 재귀테이블(recursive member)SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty

FROM CarPartsCTEINNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.PartWHERE CarParts.CarID = 1

)SELECT SubPart, SUM(Qty) AS q

Page 40: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

40

FROM CarPartsCTEGROUP BY SubPart

GO

Chapter 6 -연습 2: Apply 연산자

시나리오SQL Server 2005 에서 추가된 기능인 APPLY 연산자인 Cross Apply와 Outer Apply 연산자의 사용방법을 알아본다.

Task 1: APPLY 기본이해, 직원정보와 입사년차를 출력하는 방법이다

1. 일반적인 함수를 이용해서 출력하기.

CREATE FUNCTION dbo.FN_getYEAR(@HIREDATE AS SMALLDATETIME) RETURNS INT

ASBEGIN

DECLARE @Result SMALLINTSELECT @Result = DATEDIFF(YY,@HIREDATE,GETDATE()) +1RETURN @Result

ENDGOSELECT *, DBO.FN_getYEAR(HIREDATE) 입사년차

FROM HUMANRESOURCES.EMPLOYEEORDER BY EMPLOYEEID

2. CROSS APPLY 를이용해서출력하기.

CREATE FUNCTION dbo.FN_getYEAR2(@HIREDATE AS SMALLDATETIME) RETURNS TABLE

AS RETURNSELECT DATEDIFF(YY,@HIREDATE,GETDATE()) +1 AS 입사년차

GOSELECT *FROM HUMANRESOURCES.EMPLOYEE AS D CROSS APPLY DBO.FN_getYEAR2(D.HIREDATE) AS CA

ORDER BY EMPLOYEEID3. 단일 데이터 출력에서는 작성도 쉽고, 결과와 실행과정이 같다.

Task 2: 직원정보를 출력하고, 직원들의 레벨을 출력하는 예제이다

1. 실습을 위해 다음 두 테이블을 생성하고 데이터를 입력한다

CREATE TABLE DBO.Employees( empid int NOT NULL, mgrid int NULL, empname varchar(25) NOT NULL, salary money NOT NULL, CONSTRAINT PK_Employees PRIMARY KEY(empid),)GO

Page 41: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

41

INSERT INTO DBO.Employees VALUES(1 , NULL, 'Nancy' , $10000.00)INSERT INTO DBO.Employees VALUES(2 , 1 , 'Andrew' , $5000.00)INSERT INTO DBO.Employees VALUES(3 , 1 , 'Janet' , $5000.00)INSERT INTO DBO.Employees VALUES(4 , 1 , 'Margaret', $5000.00) INSERT INTO DBO.Employees VALUES(5 , 2 , 'Steven' , $2500.00)INSERT INTO DBO.Employees VALUES(6 , 2 , 'Michael' , $2500.00)INSERT INTO DBO.Employees VALUES(7 , 3 , 'Robert' , $2500.00)INSERT INTO DBO.Employees VALUES(8 , 3 , 'Laura' , $2500.00)INSERT INTO DBO.Employees VALUES(9 , 3 , 'Ann' , $2500.00)INSERT INTO DBO.Employees VALUES(10, 4 , 'Ina' , $2500.00)INSERT INTO DBO.Employees VALUES(11, 7 , 'David' , $2000.00)INSERT INTO DBO.Employees VALUES(12, 7 , 'Ron' , $2000.00)INSERT INTO DBO.Employees VALUES(13, 7 , 'Dan' , $2000.00)INSERT INTO DBO.Employees VALUES(14, 11 , 'James' , $1500.00)GOCREATE TABLE DBO.Departments( deptid INT NOT NULL PRIMARY KEY, deptname VARCHAR(25) NOT NULL, deptmgrid INT NULL REFERENCES Employees)GOINSERT INTO DBO.Departments VALUES(1, 'HR', 2)INSERT INTO DBO.Departments VALUES(2, 'Marketing', 7)INSERT INTO DBO.Departments VALUES(3, 'Finance', 8)INSERT INTO DBO.Departments VALUES(4, 'R&D', 9)INSERT INTO DBO.Departments VALUES(5, 'Training', 4)INSERT INTO DBO.Departments VALUES(6, 'Gardening', NULL)GO2. 직원수준을 반환하도록 함수를 작성한다

CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT) RETURNS @TREE TABLE( empid INT NOT NULL, empname VARCHAR(25) NOT NULL, mgrid INT NULL, lvl INT NOT NULL)ASBEGIN WITH Employees_Subtree(empid, empname, mgrid, lvl) AS ( -- Anchor Member (AM) SELECT empid, empname, mgrid, 0 FROM DBO.Employees WHERE empid = @empid

UNION all -- Recursive Member (RM) SELECT e.empid, e.empname, e.mgrid, es.lvl+1 FROM DBO.Employees AS e JOIN Employees_Subtree AS es ON e.mgrid = es.empid ) INSERT INTO @TREE SELECT * FROM Employees_Subtree

Page 42: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

42

RETURNENDGO3. 작성한 함수를 CROSS APPLY 연산자를 이용해 조인하여, 출력한다

SELECT *FROM DBO.Departments AS D CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST4. CROSS APPLY 가 없었다면? --> 작성이복잡하고, 실행계획이다를수있으므로성능을측정해야한다. (숙제)

5. OUTER APPLY, cross apply 에서적용되지않았던, 즉 deptmgrid 값이 null 인데이터도출력해준다

SELECT *FROM DBO.Departments AS D OUTER APPLY fn_getsubtree(D.deptmgrid) AS ST

Page 43: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

43

Chapter 6 -연습 3: 쿼리 힌트

시나리오SQL Server 2005 에서 추가된 쿼리힌트 사용방법과 효과를 알아본다.

Task 1: 계획지침 사용하기(maxdop 옵션강제)

1. 다음과 같은 ad-hoc 쿼리를 응용프로그램에서 실행한다고 가정하고 실행한다. 실행계획을 살펴본다(Ctrl+L)

SELECT TOP 1000 * FROM Sales.INDIVIDUAL ORDER BY CONTACTID ASC OPTION (MAXDOP 1)2. 이제 실행계획을 강제하도록 계획지침을 만들자

SP_CREATE_PLAN_GUIDE @name = N'AD-HOC PLAN GUIDE 1', @stmt = N'SELECT TOP 1000 * FROM Sales.INDIVIDUAL ORDER BY CONTACTID

ASC', @type = N'SQL',@module_or_batch = NULL, @params = NULL, @hints = N'OPTION (MAXDOP 2)'

GO3. 다시 한번 같은 명령을 실행하고, 실행계획을 살펴보자. 병렬처리가 되고, 비용이 줄어든 것을 확인할 수

있다

SELECT TOP 1000 * FROM Sales.INDIVIDUAL ORDER BY CONTACTID ASC4. 다음 카탈로그뷰를 이용해서 계획지침정보를 출력할 수 있다

SELECT * FROM sys.plan_guides

5. 계획지침을 삭제한다. 비활성화 시에는 'DROP' 키워드 대신, 'DISABLE' 키워드를 사용하면 된다

EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'AD-HOC PLAN GUIDE 1'GO

Task 2: DATE_CORRELATION_OPTIMIZATION 옵션을 이용하여, 날짜관련 검색 최적화하기

1. 먼저 옵션을 설정한다

ALTER DATABASE Adventureworks SET DATE_CORRELATION_OPTIMIZATION ONGO2. 다음 문장을 실행하여, 데이터베이스의 DATE_CORRELATION_OPTIMIZATION 설정을 확인한다. 맨 뒷 열인'is_date_correlation_on' 열로 확인할 수 있다

SELECT * FROM SYS.DATABASES WHERE NAME = 'ADVENTUREWORKS'

Task 3: 리컴파일

Page 44: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

44

1. 다음은 저장프로시저 내의 특정 쿼리만을 리컴파일하는 예제이다

CREATE PROC DBO.UP_EMP @EID1 INT, @EID2 INT

ASSELECT * FROM HUMANRESOURCES.EMPLOYEE

WHERE EMPLOYEEID BETWEEN @EID1 AND @EID2UNION ALLSELECT * FROM HUMANRESOURCES.EMPLOYEE

WHERE EMPLOYEEID <> 500OPTION ( RECOMPILE )

GO

Task 4: 쿼리계획을 저장해놓고, USE PLAN 을 이용하여 저장된 쿼리계획으로 실행하기

1. 먼저 프로파일러를 실행한다. 이때 다음 이벤트는 필수로 선택해야 한다

"stored procedure"의"RPC:Starting""TSQL"의"SQL:Batchstarting""Performance"의"Showplan XML"2. 실행할 쿼리는 다음과 같다. 실행하도록 한다

SELECT C.NAME, SUM(ORDERQTY) TOTAL FROM Production.ProductCategory C JOIN PRODUCTION.PRODUCT B ON

B.PRODUCTSUBCATEGORYID=C.PRODUCTCATEGORYIDJOIN SALES.SALESORDERDETAIL A ON A.PRODUCTID=B.PRODUCTID WHERE SELLSTARTDATE > '2000-01-10'GROUP BY C.NAMEHAVING SUM(ORDERQTY) > 10ORDER BY TOTAL DESC

3. 프로파일러의 "showplan xml" 행의 "text" 열에서 마우스 오른쪽 버튼을 눌러, "이벤트추출" 메뉴를 클릭한다.

4. 대화상자가 뜨면 PLAN_useplantest 라는이름을 입력하고, "D:\TSQL" 폴더에 저장한다.

5. 프로파일러를 닫는다

6. 저장한 PLAN_useplantest.sqlplan 파일을 메모장(notepad.exe)에서 연다.

7. 메모장에서 연 문서내용을 모두 복사해서, 아래 실행문의 @hints 절의? 위치에 붙여넣고 실행한다

exec sp_create_plan_guide @name = N'Guide_userplan',@stmt = N'SELECT C.NAME, SUM(ORDERQTY) TOTAL

FROM Production.ProductCategory C JOIN PRODUCTION.PRODUCT B ON B.PRODUCTSUBCATEGORYID=C.PRODUCTCATEGORYID

JOIN SALES.SALESORDERDETAIL A ON A.PRODUCTID=B.PRODUCTID WHERE SELLSTARTDATE > ''2000-01-10''GROUP BY C.NAMEHAVING SUM(ORDERQTY) > 10ORDER BY TOTAL DESC',

@type = N'SQL',@module_or_batch = NULL,@params = NULL,@hints = N'OPTION(USE PLAN N''?'')'

Page 45: 제1회 Tech Net Sql Server 2005 T Sql Enhancements

www.SQLAcademy.com

45

8. 테스트쿼리를 재실행하여, 기존 실행계획을 사용하는지 확인한다

SELECT C.NAME, SUM(ORDERQTY) TOTAL FROM Production.ProductCategory C JOIN PRODUCTION.PRODUCT B ON

B.PRODUCTSUBCATEGORYID=C.PRODUCTCATEGORYIDJOIN SALES.SALESORDERDETAIL A ON A.PRODUCTID=B.PRODUCTIDWHERE SELLSTARTDATE > '2000-01-10'GROUP BY C.NAMEHAVING SUM(ORDERQTY) > 10ORDER BY TOTAL DESC

9. 확인되었으면, 계획지침을 삭제한다

EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'Guide_userplan'GO

Task 5: 파라미터화(paramemterization)

10. 상수가 들어있는 쿼리 확인

SELECT C.NAME, SUM(ORDERQTY) TOTAL FROM Production.ProductCategory C JOIN PRODUCTION.PRODUCT B ON

B.PRODUCTSUBCATEGORYID=C.PRODUCTCATEGORYIDJOIN SALES.SALESORDERDETAIL A ON A.PRODUCTID=B.PRODUCTID WHERE SELLSTARTDATE > '2000-01-10'GROUP BY C.NAMEHAVING SUM(ORDERQTY) > 10

ORDER BY TOTAL DESC

11. 위의 쿼리를 매개변수화 할 수 있도록 템플릿으로 작성하고, 이를 output 으로 받아서 계획지침을 생성한다

DECLARE @userStatement nvarchar(max);DECLARE @userParameter nvarchar(max);EXEC sp_get_query_template N'SELECT C.NAME, SUM(ORDERQTY) TOTAL

FROM Production.ProductCategory C JOIN PRODUCTION.PRODUCT B ON B.PRODUCTSUBCATEGORYID=C.PRODUCTCATEGORYID

JOIN SALES.SALESORDERDETAIL A ON A.PRODUCTID=B.PRODUCTID WHERE SELLSTARTDATE > ''2000-01-10''GROUP BY C.NAMEHAVING SUM(ORDERQTY) > 10ORDER BY TOTAL DESC',

@userStatement OUTPUT, @userParameter OUTPUT;EXEC sp_create_plan_guide N'SALESTOTAL_GUIDE', @userStatement, N'TEMPLATE', --> 이외에ojbect, sql 유형이있다 NULL, @userParameter, N'OPTION(PARAMETERIZATION FORCED)' --> 명령의파라미터화를강제하는옵션이다GO

12. 향후 같은 쿼리를 실행할 때에는 상수에 대한 쿼리계획을 동일하게 생성할 것이다. 생성한 가이드를 삭제하도록 한다.

EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'SALESTOTAL_GUIDE'GO