SlideShare una empresa de Scribd logo
1 de 46
Hands-On Lab

실습 메뉴얼

SQL Server™ 2005:
                T-SQL Enhancements 실습
2




목 차

실습 메뉴얼....................................................................................................................................................................1
 SQL Server™ 2005:....................................................................................................................................................1
 T-SQL Enhancements 실습........................................................................................................................................1
 연습 0
 실습 설정 ..................................................................................................................................................................3
 Chapter 1 -연습 1: varchar(max) ..............................................................................................................................4
 Chapter 1 -연습 2: 행 오버플로우 지원 ................................................................................................................5
 Chapter 1 -연습 3: Snaptshot isolation level ............................................................................................................6
 Chapter 1 -연습 4: 예외 처리...................................................................................................................................8
 Chapter 2 -연습 1: TOP 연산자 기능 향상...........................................................................................................11
 Chapter 2 -연습 2: 문자셋 지원.............................................................................................................................13
 Chapter 2 -연습 3: 파티션(분할) 테이블 구성 및 성능테스트...........................................................................15
 Chapter 3 -연습 1: DDL 트리거를 이용한 로깅 및 테이블 변경 방지.............................................................18
 Chapter 3 -연습 2: DDL 트리거를 이용한 MASTER DATABASE 백업자동화..............................................20
 Chapter 3 -연습 3: XML 향상.................................................................................................................................23
 Chapter 4 -연습 1: RANKING 함수들을 이용해서, 쉽게 순위 구하기.............................................................24
 Chapter 4 -연습 2: PIVOT & UNPIVOT.................................................................................................................26
 Chapter 4 -연습 3: 시스템 정보 보기....................................................................................................................27
 Chapter 4 -연습 4: DMV..........................................................................................................................................29
 Chapter 5 -연습 1: 원격쿼리 향상..........................................................................................................................32
 Chapter 5 -연습 2: tablesample...............................................................................................................................33
 Chapter 5 -연습 3: cascade (연계참조 무결성).....................................................................................................34
 Chapter 5 -연습 4: OUTPUT..................................................................................................................................36
 Chapter 6 -연습 1: CTE...........................................................................................................................................38
 Chapter 6 -연습 2: Apply 연산자...........................................................................................................................40
 Chapter 6 -연습 3: 쿼리 힌트.................................................................................................................................43




                                                                                                                       www.SQLAcademy.com
3



     SQL Server 2005 T-SQL Enhancements


목표



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

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



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




    시나리오


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


    선수조건


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

    기본적인 윈도우 운영 환경
    기본적인 T-SQL 사용 경험
    SQL Server 2000 혹은 2005 개발 경험




    예상 소요시간: 210
    분
                      연습 0
                      실습 설정
     실습 환경 설정



                                                      www.SQLAcademy.com
4


        - SQL Server 2005 (Enterprise or Developer or Evaluation) Edition
        - 실습을 위한 예제용 데이터베이스인 Adventureworks 가 있어야 한다. 실습 시 설치하도록 한다. 설치
        되어 있지 않다면 아래 주소에서 “AdventureworksDBCI.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))
    GO
    INSERT 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_01
      SELECT SUBSTRING(VMEMO,10000,10) FROM DBO.VARMAX_01


    V   Task 2: text 컬럼에서의 substring 함수사용을 확인한다.
    .1 예제를 위한 테이블생성과 데이터를 입력한다
    CREATE TABLE DBO.TEXT_01 (TID INT, TMEMO NTEXT)
    GO
    INSERT INTO DBO.TEXT_01(TID,TMEMO) VALUES(1,REPLICATE(N'Guidelines and



                                                                             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_01
         SELECT SUBSTRING(TMEMO,10000,10) FROM DBO.TEXT_01



    T   Task 3: VARCHAR(MAX) 의기본속성을확인한다
    .1 예제를 위한 테이블생성과 데이터를 입력한다
    CREATE TABLE DBO.VARMAX_02 (VID INT, VMEMO VARCHAR(MAX))
    GO
    SELECT 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




G Task 2: 페이지크기의         한계인 8060 bytes 한계를 넘는 데이터가 잘 입력되는지 확인한다.
    .1 페이지크기의 한계인 8060 한계를 넘는 데이터가 잘 입력되는지 확인한다
    INSERT INTO DBO.ROWOVER(RID, R1, R2)
          VALUES(1, REPLICATE('A',5000), REPLICATE('A',5000))
    GO




    G 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')




                                                                   www.SQLAcademy.com
6


    SELECT *
      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_ON
      GO
    .2 DB 옵션을 ALLOW_SNAPSHOT_ISOLATION 으로 설정한다. 기본값은 OFF 이다
    ALTER DATABASE SNAPSHOT_ON
          SET ALLOW_SNAPSHOT_ISOLATION ON
      GO
    .3 옵션변경이 잘 되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다
    USE SNAPSHOT_ON
      GO
    DBCC USEROPTIONS
    GO
    SELECT NAME, snapshot_isolation_state,
          is_read_committed_snapshot_on FROM sys.databases
          WHERE NAME = 'SNAPSHOT_ON'
    .4 다음을 수행하여 트랜잭션을 시작한다. 현재 연결을 SESSION1 이라 명명한다
    --SESSION1)
    USE SNAPSHOT_ON
    GO
    CREATE TABLE DBO.SNAP_01 (SID INT, SNAME CHAR(10))



                                                                  www.SQLAcademy.com
7


GO
INSERT INTO DBO.SNAP_01(SID,SNAME) VALUES(1,'JONES')
GO
BEGIN TRAN
      UPDATE DBO.SNAP_01
            SET SNAME = 'NANCY'
.5 트랜잭션이 잘 시작되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다
--SESSION1)
SELECT * FROM sys.dm_tran_active_snapshot_database_transactions

  SELECT @@TRANCOUNT
.6 새로운 쿼리실행창을 열어서 다음 문장을 실행한다. BEFORE IMAGE 즉, 트랜잭션이 실행되기 전의
   스냅샷을 출력하는 것을 확인한다
--SESSION2)
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
GO
   SELECT * FROM DBO.SNAP_01
.7 트랜잭션을 시작했던 쿼리실행창에서 다음을 실행한다
--SESSION1)
ROLLBACK
.8 SESSION2 쿼리실행창을 닫는다
.9 같은 과정을 스냅샷옵션 변경 없이 실행해 본다. 잠금으로 인해 blocked 되는 것을 확인할 수 있다




                                                             www.SQLAcademy.com
8




    Chapter 1 -연습 4: 예외 처리

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



.    Task 1: 단순오류 발생 시 예외처리프로세스를 알아본다
    .1 예제를위한테이블과데이터를준비한다
    CREATE TABLE DBO.TRYCATCH ( TID TINYINT, TNAME CHAR(10))
    GO
    INSERT INTO DBO.TRYCATCH(TID,TNAME)
          VALUES(1,'JONES')
      GO
    .2 오류가 발생하도록 INSERT 문장을 실행하고, 예외처리블록을 지정하여 오류를 출력하도록 한다. 어떤
       오류가 발생하는지 확인하도록 한다. 아래 명령은 일괄처리로 실행되어야 하므로, 모든 영역을 선택해
       서 한번에 실행하도록 한다
    DECLARE @TRANCNT TINYINT
    BEGIN TRANSACTION
          BEGIN TRY
                INSERT INTO DBO.TRYCATCH(TID,TNAME) VALUES (300, 'INDIANA')
                WAITFOR DELAY '00:00:05'
                SET @TRANCNT = @@TRANCOUNT
                SELECT COUNT(*) AS '총갯수' FROM TRYCATCH
                COMMIT
          END TRY
          BEGIN 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 오류발생프로시저명



                                                               www.SQLAcademy.com
9


            ROLLBACK
      END CATCH
SELECT @TRANCNT AS '@@TCount'
GO




G Task 2: DEADLOCK 발생   시 예외처리하기
.1 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되,
   SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다
--SESSION1)
BEGIN TRANSACTION
BEGIN TRY
 INSERT DBO.TRYCATCH VALUES (10, 'AAAA')
 WAITFOR DELAY '00:00:05'
 SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH
 COMMIT
END TRY
BEGIN CATCH
 SELECT ERROR_NUMBER() AS '오류번호'
 ROLLBACK
END CATCH
SELECT @@TRANCOUNT AS '트랜잭션중첩수'

--SESSION2)
BEGIN TRANSACTION
BEGIN TRY
 INSERT DBO.TRYCATCH VALUES (20, 'BBBB')
 WAITFOR DELAY '00:00:05'
 SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH
 COMMIT
END TRY
BEGIN CATCH
 SELECT ERROR_NUMBER() AS '오류번호'
 ROLLBACK
END CATCH
   SELECT @@TRANCOUNT AS '트랜잭션중첩수'
.2 어떤 오류가 발생되었는지 확인한다. 오류는 발생하지 않았고, 트랜잭션은 실행되었다
--SESSION1) 에서 결과창의 데이터를 확인만 한다
.3 SESSION1 에서 실행한 트랜잭션이 제대로 COMMIT 되었는지 확인한다. COMMIT 되었다
--SESSION1)
SELECT * FROM DBO.TRYCATCH
.4 SESSION2 에는 어떤 오류가 발생되었는지 확인한다. 교착상태오류(1205 번)가 발생했고, 트랜잭션은
   ROLLBACK 되었다
--SESSION2) 에서 결과창의 데이터를 확인만 한다
.5
--SESSION1)




                                              www.SQLAcademy.com
10


  Task 3: DEADLOCK 발생 시 트랜잭션 재시도하기, 이제 교착상태가 발생하면 ROLLBACK 하고
  종료하는 것이 아닌, 트랜잭션을 재시도하도록 루틴을 작성해보자. 이 루틴은 2005 에서 데이
  터일관성을 위해 deadlock 처리를 어떻게 할 수 있는지에 대한 좋은 예가 된다
.1 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되,
   SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다
--SESSION1)
DECLARE @Tries tinyint
SET @Tries = 1
WHILE @Tries <= 3
BEGIN
 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 CATCH
END

--SESSION2)
DECLARE @Tries tinyint
SET @Tries = 1
WHILE @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 CATCH
   END
.2 SESSION2 에서 교착상태가 발생되었을 때 어떻게 실행되었는지 확인한다. 재시도 횟수를 늘려서 교착
   상태 발생 시에도 트랜잭션의 일관성을 보장하도록 할 수 있다
SELECT * FROM DBO.TRYCATCH




                                                   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 INT
    SELECT @A=COUNT(EMPLOYEEID) FROM NORTHWIND.dbo.Employees
    SELECT TOP(@A-2) * FROM NORTHWIND.dbo.Employees
          ORDER BY EMPLOYEEID DESC
      GO
    .2 1 번과 같은 로직을 사용해서 2005 환경에서 실행한다. 2005 에는 NORTHWIND 데이터베이스가 없으므
       로 ADVENTUREWORKS 데이터베이스의 PERSON.ADDRESS 테이블을 대신 이용하도록 한다. 오류 없
       이 잘 실행되는 것을 확인할 수 있다
    DECLARE @A INT
    SELECT @A=COUNT(ADDRESSID) FROM ADVENTUREWORKS.PERSON.ADDRESS
    SELECT TOP(@A-2) * FROM ADVENTUREWORKS.PERSON.ADDRESS
         ORDER BY ADDRESSID DESC
    GO




G Task 2: UPDATE 에서   TOP 사용하기




                                                          www.SQLAcademy.com
12


.1 SQL Server 2000 환경에서 TOP 을이용한 UPDATE 를실행해본다. 지원하지않는기능이므로, 오류가발생
   하는것을확인할수있다
UPDATE TOP (2) NORTHWIND.DBO.EMPLOYEES
SET EMPLOYEEID = 276
WHERE EMPLOYEEID IN (1,2,3,4,5)
GO

.2 SQL Server 2005 환경에서 TOP 을 이용한 UPDATE 를 실행한다. 잘 실행된다
BEGIN TRAN
UPDATE TOP (2) ADVENTUREWORKS.PERSON.ADDRESS
      SET AddressLine2 = 'Daehan Bldg. 3th'
      WHERE ADDRESSID IN (1,2,3,4,5)

.3 변경된 데이터를 확인한다. 그러나 실제 변경된 데이터는 임의의 데이터이며 ,어떤 데이터를 변경할
   것인지, 우리는 결정할 수 없다
SELECT * FROM ADVENTUREWORKS.PERSON.ADDRESS
      WHERE ADDRESSID IN (1,2,3,4,5)
.4 작업을 취소한다
ROLLBACK TRANSACTION
GO

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

UPDATE PERSON.ADDRESS
     SET AddressLine2 = 'Daehan Bldg. 3th'
     FROM (SELECT TOP 2 ADDRESSID AS AID FROM PERSON.ADDRESS
                               ORDER BY ADDRESSID DESC
                         )
                         AS A
     WHERE ADDRESSID = A.AID
GO
.6 실행결과를 확인한다
SELECT TOP 10 * FROM ADVENTUREWORKS.PERSON.ADDRESS
      ORDER BY ADDRESSID DESC




D Task 3: DELETE 에서   TOP 사용하기
.1 DELETE 를 이용해 삭제할 수 있다. 아래 문장을 실행해서 확인한다. 잘 실행된다
BEGIN TRAN
DELETE TOP (20)
      FROM Purchasing.PurchaseOrderDetail
      WHERE DueDate < '20020701'

.2 작업을 취소한다
ROLLBACK TRAN




                                                      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 TEST
    GO
    USE TEST
    GO

    .2 테이블을 생성하되, 문자 컬럼을 일반 유니코드형식으로 작성한다
    CREATE TABLE DBO.KOR (KID INT, KNAME VARCHAR(50) COLLATE KOREAN_WANSUNG_CI_AS)
    GO

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



                                                           www.SQLAcademy.com
14


INSERT INTO DBO.KOR(KID,KNAME)
      VALUES(1, 'ᆟ')
GO
SELECT * FROM KOR
SELECT UNICODE(KNAME) FROM DBO.KOR

.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)
GO
SELECT KID, CAST(KNAME AS NVARCHAR(50)) COLLATE KOREAN_90_CI_AS FROM DBO.KOR2
SELECT UNICODE(KNAME) FROM DBO.KOR2

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




                                                       www.SQLAcademy.com
15




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

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



.    Task 1: 실습을 위한 데이터베이스 준비.
    .1 4 개의 추가 데이터파일과 각각의 파일이 포함되는 파일그룹으로 구성되도록 데이터베이스를 생성한
       다
    CREATE DATABASE PARTITIONTEST
    GO

    ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG1
    GO
    ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG2
    GO
    ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG3
    GO
    ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG4
    GO
    ALTER DATABASE PARTITIONTEST ADD
    FILE(NAME='FILE11',FILENAME='C:CFILE11.NDF',SIZE=10) TO FILEGROUP FG1
    GO
    ALTER DATABASE PARTITIONTEST ADD
    FILE(NAME='FILE22',FILENAME='C:DFILE22.NDF',SIZE=10) TO FILEGROUP FG2
    GO
    ALTER DATABASE PARTITIONTEST ADD
    FILE(NAME='FILE33',FILENAME='C:EFILE33.NDF',SIZE=10) TO FILEGROUP FG3
    GO
    ALTER DATABASE PARTITIONTEST ADD




                                                              www.SQLAcademy.com
16


FILE(NAME='FILE44',FILENAME='C:FFILE44.NDF',SIZE=10) TO FILEGROUP FG4
GO




G Task 2: 파티션구성, 파티션함수생성->파티션스킴생성->테이블생성.
.1 날짜를 기준으로 4 부분으로 분할 입력하게 해 주는, 파티션함수(function)를 생성한다
USE PARTITIONTEST
GO

CREATE PARTITION FUNCTION DBO.DateFn(smalldatetime)
     AS RANGE RIGHT FOR VALUES ('20000101', '20030101','20060101')                  -- 오른쪽값
을기준값으로줌
GO

.2 생성한 함수의 날짜범위에 파일그룹이 할당되도록, 파티션스킴(scheme)을 작성한다
CREATE PARTITION SCHEME DBO.DateScheme
     AS PARTITION DateFn TO (fg1,fg2,fg3,fg4)
GO



G 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 INT
SET @NO=0
WHILE @NO < 1000
BEGIN
      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+1
END
SET NOCOUNT ON
GO

.3 입력된 데이터를 확인한다
SELECT COUNT(*) FROM DBO.CardAppr
SELECT max(apprdate) FROM DBO.CardAppr
SELECT * FROM DBO.CardAppr order by cid




                                                                  www.SQLAcademy.com
17


.4 파티션 범위를 확인한다
SELECT $partition.DateFn(ApprDate) AS 파티션번호
      , min(ApprDate) AS MinDate
      , max(ApprDate) AS MaxDate
      , 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.partitions
      WHERE object_id = OBJECT_ID('CardAppr')
      ORDER BY partition_number, index_id
GO




G Task 4: 실제로   특정날짜만을 질의하는 쿼리를 실행했을 때, 해당파티션만을 검색하는지 확인한
  다.
.1 인덱스를 생성한다.
CREATE clustered INDEX ix_CardAppr_ApprDate ON DBO.CardAppr (ApprDate, cid)
     ON DateScheme(ApprDate)
GO

.2 실행계획을 확인한다. StmtText 열의 끝부분을 확인하면 된다
SET STATISTICS PROFILE ON
GO
SELECT * FROM DBO.CardAppr WHERE ApprDate ='20030101'
SET STATISTICS PROFILE OFF




                                                             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_CREATETAB
         ON DATABASE FOR CREATE_TABLE
    AS
         INSERT INTO DBO.DDLLOG VALUES( EVENTDATA())
         --DDL 트리거를실행하는이벤트에대한정보는EVENTDATA 함수를사용하여캡처할수있다
         --이함수는XML 값을반환한다
    GO

    .3 실제로 테이블을 생성해 본다
    CREATE TABLE DBO.SSS( SID INT PRIMARY KEY IDENTITY, SNAME VARCHAR(MAX))
    GO




                                                             www.SQLAcademy.com
19


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




    Task 2: 테이블 생성내역을 문자열기록으로 남기기.
.1 기록을 남기는 작업을 포함하는 DDL 트리거를 작성한다
CREATE TRIGGER TRG_CREATETAB2
        ON 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 )’




C   Task 3: 특정 테이블에 대한 삭제작업을 금지시키기.
.1 삭제대상이 될 테이블을 작성한다
CREATE TABLE DBO.ZZZ(ZID INT, ZNAME VARCHAR(10))
GO

.2 DROP_TABLE 이벤트에 대하여, 'ZZZ' 테이블이라면 롤백하는 DDL 트리거를 작성한다
CREATE TRIGGER TRG_PREVENT_DROPTTT
        ON DATABASE FOR DROP_TABLE
AS
        DECLARE @TAB TABLE( TNAME VARCHAR(MAX))
        INSERT @TAB
        SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)
[1]','NVARCHAR(MAX)')
        -- SELECT * FROM @TAB
        IF EXISTS(SELECT * FROM @TAB WHERE TNAME LIKE '%ZZZ%')
        BEGIN
               ROLLBACK
        END
GO

.3 DROP TABLE 문장을 각각 조건에 없는 테이블(SSS)와, 조건에 해당하는 테이블(ZZZ)에 대하여 실행
   한다
DROP TABLE DBO.SSS             --> 트리거발생되지않음
GO



                                                         www.SQLAcademy.com
20


    DROP TABLE DBO.ZZZ         --> 트리거발생됨
    GO

    .4 ROLLBACK 처리가 되었는지 확인한다
    SELECT * FROM DBO.SSS   --> 삭제됨
    SELECT * FROM DBO.ZZZ   --> 롤백되어삭제되지않았음

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




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

    시나리오
       1. 사용자정의 메시지를 생성한다.
       2. master 데이터베이스에 변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다.
       3. master 데이터베이스를 백업하는 job 을 생성한다.
       4. 메시지이벤트가 발생되면 자동으로 백업 job 을 수행하도록, 경고를 작성한다.
       5. 실제로 master 데이터베이스 변경작업을 시도하여, 백업이 되는지 확인한다.



.    Task 1: 사용자정의 메시지를 생성한다.
    .1 master 데이터베이스에서 작업한다
    Use Master
    GO

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

    EXEC sp_addmessage 50001, 10, N'Master Database has changed' ,   'us_english',



                                                      www.SQLAcademy.com
21


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



G Task 2: master 데이터베이스에         변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다.
    .1 트리거 작성
    Create trigger Trg_Master_BackupAutomation_Server
           on all SERVER
           for
                   CREATE_DATABASE , ALTER_DATABASE, DROP_DATABASE , DDL_LOGIN_EVENTS,
    DDL_GDR_SERVER_EVENTS, DDL_AUTHORIZATION_SERVER_EVENTS ,
    DDL_ENDPOINT_EVENTS
    as
           Raiserror (50001, 10, 1) with log
    GO



G 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:TSQLMaster.bak' with Init, Format
           GO
         .vi “구문분석” 버튼을 누른다. 이때 오류가 없어야 한다.
         .vii “고급/성공한경우동작” 항목은 “성공보고와함께작업종료” 를 선택한다.
         .viii“확인” 버튼을 누른다.
      .d “확인” 버튼을 누른다.


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




                                                                  www.SQLAcademy.com
22


    .1 SSMS 의 개체탐색기의 “SQL Server 에이전트/경고” 항목에서 마우스 오른쪽버튼을 클릭하고, “새경고
       ” 버튼을 누른다. 창이 열리면 다음을 실행한다
      .a “일반/이름” 항목에 “Master 데이터베이스백업자동화”를 입력한다.
      .b “일반/유형” 항목에서 “SQL Server 이벤트경고” 를 선택한다.
      .c “일반/데이터베이스이름” 항목에서 “Master” 를 선택한다.
      .d “일반/경고발생기준” 항목은 “오류번호” 옵션을 선택하고, “50001”을 입력한다.
      .e “응답/작업실행” 체크박스에 체크표시한다.
      .f “응답/작업실행”의 목록에서, 사전에 작업을 생성해 둔, “Master 데이터베이스백업”을 선택한다.
      .g “확인” 버튼을 누른다.


.    Task 5: 실제로 master 데이터베이스변경작업을시도하여, 백업이되는지확인한다
    .1 다음 작업들을 실행해서, 실제로 Master 데이터베이스에 대한 자동백업이 수행되는지 확인한다
      .a SSMS 의 쿼리실행창에서 다음 명령을 수행하고, 탐색기의 ‘D:TSQL” 폴더 내에 “Master.bak” 가
         생성되었는지 각각의 명령에 대해 확인한다.
      CREATE DATABASE TRG
      GO
      DROP DATABASE TRG
      GO

      .b 역시 다음 명령을 실행하고, 탐색기의 ‘D:TSQL” 폴더 내에 “Master.bak” 가 생성되었는지 각각의
         명령에 대해 확인한다.
      CREATE LOGIN AAA WITH PASSWORD = 'Pa$$w0rd'
      GO
      DROP LOGIN AAA
      GO

    .2 서버 수준의 DDL 트리거를 삭제하는 방법은 다음과 같다
    DROP TRIGGER Trg_Master_BackupAutomation_Server on all SERVER

    GO




                                                               www.SQLAcademy.com
23




    Chapter 3 -연습 3: XML 향상

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



.    Task 1: XML 형식으로 데이터를 출력하여, 응용프로그램으로 반환할 수 있다.
    .1 기존에 저장되어 있는 NON XML 컬럼을 XML 로 출력 가능함. 이때 자동으로 타입변경가능
    USE ADVENTUREWORKS
    GO

    SELECT ContactID, FirstName, LastName, Phone
          FROM Person.Contact
          ORDER BY ContactID
          FOR XML AUTO, TYPE


T    Task 2: 출력(SELECT) 뿐 아니라, 입력과 수정에도 사용 가능하다는 것을 확인한다.
    .1 XML 형식을 갖는 컬럼을 포함하여 테이블을 생성하고 데이터를 입력한다
    CREATE TABLE DBO.T1(intCol int, XmlCol xml)
    GO
    INSERT INTO DBO.T1
    VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>')
    GO




                                                                www.SQLAcademy.com
24


    .2 XML 형식 컬럼을 조회해서, 다른 테이블의 XML 컬럼에 입력 가능하다
    CREATE TABLE DBO.T2(XmlCol xml)
    GO
    INSERT INTO DBO.T2(XmlCol)
    SELECT (SELECT XmlCol.query('/Root')
        FROM DBO.T1
        FOR XML AUTO,TYPE)
    GO


    .3 결과를 확인한다
    SELECT * FROM DBO.T2




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

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



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

    SELECT P.Name Product, P.ListPrice, PSC.Name Category,
          RANK() OVER(ORDER BY P.ListPrice )
          AS PriceRank
          FROM Production.Product P JOIN Production.ProductSubCategory PSC
          ON P.ProductSubCategoryID = PSC.ProductSubCategoryID
          ORDER BY 2, 4

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




                                                                 www.SQLAcademy.com
25


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




    Task 2: DENSE_RANK () 함수 기능이해
.1 아래 문장을 실행해서 DENSE_RANK() 함수의 기능을 이해한다. 결과를 보면 Category 값이 Gloves,
   handlesbars 인 예에서 동점과 상관없이 점수 자체로만 랭킹하고 있음을 알 수 있다
SELECT P.Name Product, P.ListPrice, PSC.Name Category,
       DENSE_RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC)     AS
PriceRank
       FROM Production.Product P JOIN Production.ProductSubCategory PSC
       ON P.ProductSubCategoryID = PSC.ProductSubCategoryID
       ORDER BY 3,4




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.ListPrice
      FROM Production.Product P JOIN Production.ProductSubCategory PSC
      ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN
Production.ProductCategory PC
      ON PSC.ProductCategoryID = PC.ProductCategoryID
      ORDER BY 2,1




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.ListPrice
      FROM Production.Product P JOIN Production.ProductSubCategory PSC
      ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN
Production.ProductCategory PC
      ON PSC.ProductCategoryID = PC.ProductCategoryID
      ORDER BY 2,4




                                                             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))
    GO
    INSERT 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')
    GO
    .2 2005 에서의 설계-->설계단순화 및 저장공간 감소
    CREATE TABLE MEMBER2 (MID INT IDENTITY PRIMARY KEY, MNAME NVARCHAR(50), FAVORITE
    NVARCHAR(20))



                                                            www.SQLAcademy.com
27


    GO
    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'영화')
    INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'뮤지컬')
      GO
    .3 관심분야종류를 파악한다
    SELECT DISTINCT FAVORITE FROM DBO.MEMBER2

    .4 필요한 관심분야 종류별로 회원 별 개수를 출력한다
    SELECT * FROM DBO.MEMBER2
          PIVOT (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.DATABASES
    .3 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다
    SELECT * FROM SYS.TABLES ORDER BY NAME
    .4 도움말의 색인항목의 찾을 대상 textbox 에서 "SYS."을 입력한 후 나타나는 카탈로그뷰의 목록을 확인
       한다




한Task 2: 일반적으로       사용할 수 있는 정보스키마뷰를 사용해 본다
    .1 다음을 실행하면 데이터베이스 내의 모든 테이블과 뷰정보를 볼 수 있다



                                                           www.SQLAcademy.com
28


SELECT * FROM INFORMATION_SCHEMA.TABLES
.2 다음을 실행하면 WHERE 절에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'ADDRESS'
.3 도움말의 색인항목의 찾을대상 textbox 에서 "INFORMATION_" 을 입력한 후 나타나는 카탈로그뷰의
   목록을 확인한다




확Task 3: 일반적으로    사용되는 호환성뷰를 사용해본다
.1 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다. SYS.OBJECTS 와 비교해보자. ID
   컬럼명 등이 다르고 출력하는 속성목록이 다른 것을 확인할 수 있다
SELECT * FROM SYSOBJECTS
.2 다음을 실행하면 현재 실행계획캐쉬에 저장되어 있는 명령들을 확인할 수 있다
SELECT * FROM SYS.SYSCACHEOBJECTS
.3 다음을 실행하면 WHERE 절 에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다
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




h   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



h   Task 5: 일반적으로 사용할 수 있는 시스템프로시저를 사용해본다
.1 다음을 실행하면 현재 인스턴스의 DB 버전과 OS 버전 등을 확인할 수 있다
EXEC DBO.XP_MSVER
.2 다음을 실행하면 지정한 테이블의 제약정보를 확인할 수 있다
EXEC DBO.SP_HELPCONSTRAINT 'PERSON.ADDRESS'
.3 다음을 실행하면 지정한 테이블의 컬럼정보를 확인할 수 있다
EXEC DBO.SP_COLUMNS 'ADDRESS', 'PERSON'



                                                            www.SQLAcademy.com
29




    Chapter 4 -연습 4: DMV

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



.    Task 1: 실습준비
    .1 아래 문장을 10 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다
    SELECT * FROM Sales.SalesOrderDetail
    SELECT * FROM Sales.Individual
    .2 --2. 아래 문장을 50 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다
    SELECT * FROM PRODUCTION.CULTURE




C    Task 2: sys.dm_exec_query_stats 동적뷰를 질의하여, 리소스를 많이 차지하고 있는 상위쿼리를 확
     인한다
    .1 sys.dm_exec_query_stats 의 기본정보를 확인한다.
    SELECT * FROM SYS.dm_exec_query_stats
    .2 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_exec_query_stats" 을 입력하여, 이 뷰의 속성정보를
       확인한다. total_worker_time,execution_count, total_physical_reads, last_physical_reads 등을 특히 확인한다



                                                                       www.SQLAcademy.com
30


.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 qs
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
        ORDER 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,
     ((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 qs
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
        ORDER 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 qs
       CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
       ORDER BY last_logical_reads DESC




D Task 3: sys.dm_exec_cached_plans 동적뷰를   질의하여, 캐시된 플랜정보를 확인한다
.1 sys.dm_exec_cached_plans 의 기본정보를 확인한다.
SELECT * FROM SYS.dm_exec_cached_plans
.2 도움말의 색인항목의 찾을대상 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 cp
      CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
      ORDER BY usecounts DESC, refcounts DESC
.4 캐쉬된 플랜에 대한 메모리점유량 별 상위 100 개의 쿼리를 확인한다. 상위문장을 확인한다




                                                               www.SQLAcademy.com
31


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 st
        WHERE cacheobjtype = 'Compiled Plan' AND st.text not like '%sys%'
        ORDER BY 3 DESC, 5 DESC
GO
.5 아래를 각각 따로따로 여러번(5 번정도) 실행한 뒤, 위 4 번 문장을 다시한번 실행해본다. WHERE 을 사
    용하지 않은 명령은 인덱스를 사용하지 못했으므로 50 PAGE, 사용한 명령은 인덱스를 사용했으므로 2
    PAGE 만을 점유하고 있는 것을 알 수 있다
SELECT * FROM SALES.INDIVIDUAL
SELECT * FROM SALES.INDIVIDUAL WHERE CUSTOMERID = 11000




 Task 4: sys.dm_tran_database_transactions 동적뷰를 질의하여, 의미있는 트랜잭션 중에서 로그생
 성수 기준 상위 트랜잭션을 확인한다
.1 sys.dm_tran_database_transactions 의기본정보를확인한다.
SELECT * FROM SYS.dm_tran_database_transactions
.2 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_tran_database_transactions" 을 입력하여, 이 뷰의 속
   성정보를 확인한다.
.3 각기 다른 3 개의 쿼리실행창을 열어서 각각 다음 문장을 실행한다. 각각의 창은 SESSION1,
   SESSION2, SESSION3 으로 명명한다.
--SESSION1)
USE ADVENTUREWORKS
GO
BEGIN TRAN
      UPDATE PERSON.ADDRESS
            SET ADDRESSLINE2 = 'SEOUL'
--SESSION2)
USE ADVENTUREWORKS
GO
BEGIN TRAN
      UPDATE SALES.INDIVIDUAL
            SET CONTACTID = '11101'
--SESSION3)
USE ADVENTUREWORKS
GO
BEGIN TRAN
      UPDATE Sales.Customer
            SET MODIFIEDDATE = GETDATE()
.4 현재 서버의 트랜잭션정보를, 아래 명령을 실행해서 확인한다
USE MASTER
GO
SELECT TRANSACTION_ID, DB_NAME(DATABASE_ID) AS DB명,
DATABASE_TRANSACTION_BEGIN_TIME
      , CASE DATABASE_TRANSACTION_TYPE WHEN 1 THEN '읽기/쓰기' WHEN 2 THEN '읽기전



                                                          www.SQLAcademy.com
32


    용' 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_transactions
          WHERE DATABASE_TRANSACTION_BEGIN_TIME IS NOT NULL
          ORDER BY [생성된로그행수] DESC




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


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

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



.    Task 1: EXECUTE .. AT 을 이용하여 쿼리하기
    .1 먼저 원격서버를 등록한다. 만일 원격서버대상이 없는 경우에는 로컬서버에 있는 인스턴스를 등록하
       도록 한다
      .a 만일 로컬서버의 인스턴스명을 모르는 경우, 다음 명령을 실행해서 확인할 수 있다
      SELECT * FROM SYS.SERVERS
      .b 만일 로컬서버의 인스턴스명을 확인했다면 다음을 실행하면 된다
    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 일반적으로 사용하는 원격쿼리. 실행계획을 로컬서버가 생성하고 로컬에서 실행한다



                                                            www.SQLAcademy.com
33


      SELECT * FROM CEYX2.NORTHWIND.DBO.EMPLOYEES
          WHERE EMPLOYEEID = 1
      .b 일반적으로 사용하는 통과쿼리. 실행계획을 원격서버가 생성하고 원격에서 실행한다. 그러므로 정
         확한 실행계획을 출력하지 않는다
      --> !!!!!!!!! 로컬서버에 대해서는 실행되지 않으므로 위 문장은 실패한다.
      --> !!!!!!!!! 그러므로 다음 옵션을 설정하고 재실행하도록 한다.
      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'
      GO
      EXECUTE ('SELECT *
          FROM NORTHWIND.DBO.EMPLOYEES
          WHERE EMPLOYEEID = ? ', 1) AT CEYX2
       GO




    Chapter 5 -연습 2: tablesample

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



.    Task 1: tablesample 성능비교, 개발/유지보수 시 흔히 실행하는 top 과 2005 tablesample 과의 성능
     비교
    .1 데이터베이스 연결을 변경한다. 다음을 실행하면 된다
    USE Adventureworks
    GO
    .2 다음 두 문장을 실행한다
    SELECT * FROM SALES.INDIVIDUAL
           TABLESAMPLE (100 ROWS)
    GO
    SELECT TOP 100 * FROM SALES.INDIVIDUAL
    GO
    .3 2 번 단계의 두 문장을 영역으로 선택하고, SSMS 의 "예상실행계획보기" 단추를 누르거나, Ctrl+L 을 누
       른다. 이때 출력되는 실행계획을 비교해 본다. 얼마나차이가나는지확인한다




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



                                                        www.SQLAcademy.com
34


    .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)




    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))
    GO
    INSERT 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')
    GO
    ALTER TABLE DBO.ACTOR
          ADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES
    MOVIE(MCODE)
          ON UPDATE CASCADE ON DELETE CASCADE
    GO
    INSERT 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')



                                                              www.SQLAcademy.com
35


INSERT INTO DBO.ACTOR VALUES(5,'타마키히로시','B200')
GO
.2 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해 본다. CASCADE 옵션이 설정되어 있지 않았다면
   RUNTIME 오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 변경된다
UPDATE DBO.MOVIE
      SET MCODE = 'H555' WHERE MCODE = 'B200'
GO
.3 잘 변경되었는지 확인한다
SELECT * FROM DBO.MOVIE
SELECT * FROM DBO.ACTOR
.4 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. CASCADE 옵션이 설정되어 있지 않았다면 RUNTIME
   오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 삭제된다
DELETE FROM DBO.MOVIE WHERE MCODE = 'A100'
GO
.5 잘 삭제되었는지 확인한다
SELECT * FROM DBO.MOVIE
SELECT * FROM DBO.ACTOR
.6 두 테이블을 모두 삭제한다
DROP TABLE DBO.ACTOR
GO
DROP TABLE DBO.MOVIE
GO


G Task 2: cascade 의 SET NULL, SET DEFAULT 옵션이해
.1 위에서 실행했던 task1 의 1 번단계의 스크립트를 한번 더 실행한다. 다만 ALTER 문은 다음 문으로 대
   체해서 실행하도록 한다
ALTER TABLE DBO.ACTOR
       ADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES
MOVIE(MCODE)
       ON UPDATE SET DEFAULT ON DELETE SET NULL
GO
.2 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해본다. 자식테이블값이 동시에 DEFAULT 값인
   'A100' 으로 변경된다
UPDATE DBO.MOVIE
      SET MCODE = 'H555' WHERE MCODE = 'B200'
GO
.3 잘 변경되었는지 확인한다
SELECT * FROM DBO.MOVIE
SELECT * FROM DBO.ACTOR
.4 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. 자식테이블값이 동시에 NULL 값으로 변경된다
DELETE FROM DBO.MOVIE WHERE MCODE = 'A100'
GO
.5 잘 삭제되었는지 확인한다
SELECT * FROM DBO.MOVIE
SELECT * FROM DBO.ACTOR
.6 두 테이블을 모두 삭제한다
DROP TABLE DBO.ACTOR




                                                 www.SQLAcademy.com
36


    GO
    DROP TABLE DBO.MOVIE
    GO




    Chapter 5 -연습 4: OUTPUT

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



.    Task 1: 삭제정보를 반환하는 OUTPUT
    .1 예제를 위한 테이블을 생성한다
    CREATE TABLE DBO.OUTPUT_01(OID INT,ONAME VARCHAR(20))
    GO
    INSERT INTO DBO.OUTPUT_01 VALUES(1,'AAA')
    INSERT INTO DBO.OUTPUT_01 VALUES(2,'BBB')
    INSERT INTO DBO.OUTPUT_01 VALUES(3,'CCC')
    GO
    .2 삭제를 실행하되, 삭제된 행을 반환하도록 OUTPUT 절을 설정한다
    DELETE DBO.OUTPUT_01
       OUTPUT DELETED.*
          WHERE OID IN (1,2)
    GO
    .3 다음 문장은 SQL Server 2000 에서, OUTPUT 기능을 구현한 예이다
    CREATE TRIGGER DBO.TRG_OUTPUT_01
         ON OUTPUT_01 FOR DELETE
    AS




                                                            www.SQLAcademy.com
37


      SELECT * FROM DELETED
GO
DROP TRIGGER DBO.TRG_OUTPUT_01
GO




G Task 2: 수정정보를   기록하도록 OUTPUT 사용
.1 수정정보를 기록할 테이블을 생성한다
CREATE TABLE DBO.OUTPUT_01_History
     ( HID INT IDENTITY, OID INT, BeforeONAME VARCHAR(20), AfterONAME VARCHAR(20),
CHANGEDATE DATETIME )
GO
.2 수정정보를 기록하도록 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'
       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
GO
.3 기록테이블에 수정 전후 데이터가 잘 입력되었는지 확인한다
SELECT * FROM DBO.OUTPUT_01_History




                                                          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 B
          ON A.managerid = B.employeeid
          GROUP BY B.LoginID
          ORDER BY B.LoginID
    .2 CTE 를 사용한 쿼리문장을 실행한다. 그리고 실행계획을 확인한다. 직접 작성한 재귀쿼리와 차이가 있
       는가 (없다)
    WITH CTETable(ManagerID) AS
          (
     SELECT ManagerID
     FROM HumanResources.Employee AS e
     WHERE ManagerID IS NOT NULL



                                                         www.SQLAcademy.com
39


      )
SELECT B.LoginID, count(*)
      FROM CTETable JOIN HumanResources.Employee B
      ON B.EmployeeID = CTETable.ManagerID
  GROUP BY LoginID
      ORDER BY B.LoginID
GO




G Task 2: 테이블변수를      이용하여 재실행
.1 테이블변수를 사용하여 실행한다. 역시 실행계획을 살펴본다. 차이가 있는가 (테이블변수를 사용한 것
   이 느리다)
DECLARE @TAB TABLE(ManagerID INT)
INSERT @TAB
  SELECT ManagerID
  FROM HumanResources.Employee AS e
  WHERE ManagerID IS NOT NULL
SELECT B.LoginID, count(*)
      FROM @TAB A JOIN HumanResources.Employee B
      ON B.EmployeeID = A.ManagerID
  GROUP BY LoginID
      ORDER BY B.LoginID




L   Task 3: 상관관계 하위쿼리구현방법과 CTE 구현방법과의 성능비교, 역시 실행계획을 비교해본
    다 (성능은 동일하다)
.1 상관관계 하위쿼리로 작성
SELECT * FROM Sales.SalesOrderDetail A
       WHERE 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.SalesOrderDetail
      GROUP BY PRODUCTID
      )
SELECT * FROM Sales.SalesOrderDetail A
      WHERE 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)
GO
INSERT DBO.CarParts VALUES (1, 'Body', 'Door', 4)



                                                                www.SQLAcademy.com
40


    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)
    GO
    .2 CTE 를 이용해서 좀 더 단순하게 부품별 하위부품개수를 출력한다
    WITH CarPartsCTE(SubPart, Qty)
    AS
    (
    -- 기준테이블(anchor member)
    SELECT SubPart, Qty
          FROM DBO.CarParts
          WHERE Part = 'Body'
    UNION ALL
    -- 재귀테이블(recursive member)
    SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty
          FROM CarPartsCTE
          INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part
          WHERE CarParts.CarID = 1
    )
    SELECT SubPart, SUM(Qty) AS q
          FROM CarPartsCTE
          GROUP 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
    AS
    BEGIN
          DECLARE @Result SMALLINT
          SELECT @Result = DATEDIFF(YY,@HIREDATE,GETDATE()) +1
          RETURN @Result
    END
    GO
    SELECT *, DBO.FN_getYEAR(HIREDATE) 입사년차
          FROM HUMANRESOURCES.EMPLOYEE
          ORDER BY EMPLOYEEID
    .2 CROSS APPLY 를이용해서출력하기.



                                                                  www.SQLAcademy.com
41


    CREATE FUNCTION dbo.FN_getYEAR2(@HIREDATE AS SMALLDATETIME)
          RETURNS TABLE
    AS RETURN
          SELECT DATEDIFF(YY,@HIREDATE,GETDATE()) +1 AS 입사년차
    GO
    SELECT *
    FROM HUMANRESOURCES.EMPLOYEE AS D
      CROSS APPLY DBO.FN_getYEAR2(D.HIREDATE) AS CA
          ORDER BY EMPLOYEEID
    .3 단일 데이터 출력에서는 작성도 쉽고, 결과와 실행과정이 같다.




.    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
    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)
    GO
    CREATE TABLE DBO.Departments
    (
      deptid INT NOT NULL PRIMARY KEY,
      deptname VARCHAR(25) NOT NULL,
      deptmgrid INT NULL REFERENCES Employees
    )
    GO
    INSERT 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)
    GO



                                                                 www.SQLAcademy.com
42


.2 직원수준을 반환하도록 함수를 작성한다
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
)
AS
BEGIN
  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

  RETURN
END
GO
.3 작성한 함수를 CROSS APPLY 연산자를 이용해 조인하여, 출력한다
SELECT *
FROM DBO.Departments AS D
  CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST
.4 CROSS APPLY 가 없었다면? --> 작성이복잡하고, 실행계획이다를수있으므로성능을측정해야한다. (숙
   제)
.5 OUTER APPLY, cross apply 에서적용되지않았던, 즉 deptmgrid 값이 null 인데이터도출력해준다
SELECT *
FROM DBO.Departments AS D
 OUTER APPLY fn_getsubtree(D.deptmgrid) AS ST




                                                          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)'




                                                              www.SQLAcademy.com
44


    GO
    .3 다시 한번 같은 명령을 실행하고, 실행계획을 살펴보자. 병렬처리가 되고, 비용이 줄어든 것을 확인할
       수 있다
    SELECT TOP 1000 * FROM Sales.INDIVIDUAL ORDER BY CONTACTID ASC
    .4 다음 카탈로그뷰를 이용해서 계획지침정보를 출력할 수 있다
      SELECT * FROM sys.plan_guides
    .5 계획지침을 삭제한다. 비활성화 시에는 'DROP' 키워드 대신, 'DISABLE' 키워드를 사용하면 된다
    EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'AD-HOC PLAN GUIDE 1'
    GO




G Task 2: DATE_CORRELATION_OPTIMIZATION 옵션을         이용하여, 날짜관련 검색 최적화하기
    .1 먼저 옵션을 설정한다
    ALTER DATABASE Adventureworks
      SET DATE_CORRELATION_OPTIMIZATION ON
    GO
    .2 다음 문장을 실행하여, 데이터베이스의 DATE_CORRELATION_OPTIMIZATION 설정을 확인한다. 맨
       뒷 열인'is_date_correlation_on' 열로 확인할 수 있다
    SELECT * FROM SYS.DATABASES WHERE NAME = 'ADVENTUREWORKS'




'    Task 3: 리컴파일
    .1 다음은 저장프로시저 내의 특정 쿼리만을 리컴파일하는 예제이다
    CREATE PROC DBO.UP_EMP
          @EID1 INT, @EID2 INT
    AS
    SELECT * FROM HUMANRESOURCES.EMPLOYEE
          WHERE EMPLOYEEID BETWEEN @EID1 AND @EID2
    UNION ALL
    SELECT * FROM HUMANRESOURCES.EMPLOYEE
          WHERE EMPLOYEEID <> 500
          OPTION ( RECOMPILE )
    GO




G Task 4: 쿼리계획을       저장해놓고, USE PLAN 을 이용하여 저장된 쿼리계획으로 실행하기
    .1 먼저 프로파일러를 실행한다. 이때 다음 이벤트는 필수로 선택해야 한다
    "stored procedure"의"RPC:Starting"
    "TSQL"의"SQL:Batchstarting"
    "Performance"의"Showplan XML"
    .2 실행할 쿼리는 다음과 같다. 실행하도록 한다
    SELECT C.NAME, SUM(ORDERQTY) TOTAL



                                                             www.SQLAcademy.com
45


      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.NAME
      HAVING SUM(ORDERQTY) > 10
      ORDER 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.NAME
       HAVING SUM(ORDERQTY) > 10
       ORDER BY TOTAL DESC',
@type = N'SQL',
@module_or_batch = NULL,
@params = NULL,
@hints = N'OPTION(USE PLAN N''?'')'
.8 테스트쿼리를 재실행하여, 기존 실행계획을 사용하는지 확인한다
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.NAME
      HAVING SUM(ORDERQTY) > 10
      ORDER BY TOTAL DESC
.9 확인되었으면, 계획지침을 삭제한다
EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'Guide_userplan'
GO




G Task 5: 파라미터화(paramemterization)
.10 상수가 들어있는 쿼리 확인
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.NAME



                                                             www.SQLAcademy.com
46


     HAVING 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.NAME
      HAVING SUM(ORDERQTY) > 10
      ORDER 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




                                                          www.SQLAcademy.com

Más contenido relacionado

La actualidad más candente

BlOOM FILTER의 이해와 활용방법_Wh oracle
BlOOM FILTER의 이해와 활용방법_Wh oracleBlOOM FILTER의 이해와 활용방법_Wh oracle
BlOOM FILTER의 이해와 활용방법_Wh oracle엑셈
 
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracle
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracleORACLE EXADATA HCC 압축방식 이해하기_Wh oracle
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracle엑셈
 
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천탑크리에듀(구로디지털단지역3번출구 2분거리)
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle엑셈
 
Tungsten 을활용한 MySQL / Hadoop 동기화
Tungsten 을활용한 MySQL / Hadoop 동기화Tungsten 을활용한 MySQL / Hadoop 동기화
Tungsten 을활용한 MySQL / Hadoop 동기화I Goo Lee
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL TuningPgDay.Seoul
 
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracleSQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle엑셈
 
Federated Engine 실무적용사례
Federated Engine 실무적용사례Federated Engine 실무적용사례
Federated Engine 실무적용사례I Goo Lee
 
MySQL GTID 시작하기
MySQL GTID 시작하기MySQL GTID 시작하기
MySQL GTID 시작하기I Goo Lee
 
SQL PlAN MANAGEMENT 활용_Wh oracle
SQL PlAN MANAGEMENT 활용_Wh oracleSQL PlAN MANAGEMENT 활용_Wh oracle
SQL PlAN MANAGEMENT 활용_Wh oracle엑셈
 
redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바NeoClova
 
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Commit Wait Class 대기시간 감소 방안_Wh oracle
Commit Wait Class 대기시간 감소 방안_Wh oracleCommit Wait Class 대기시간 감소 방안_Wh oracle
Commit Wait Class 대기시간 감소 방안_Wh oracle엑셈
 
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQLI Goo Lee
 
대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle엑셈
 
SSD 개념 및 활용_Wh oracle
SSD 개념 및 활용_Wh oracleSSD 개념 및 활용_Wh oracle
SSD 개념 및 활용_Wh oracle엑셈
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용I Goo Lee
 

La actualidad más candente (20)

BlOOM FILTER의 이해와 활용방법_Wh oracle
BlOOM FILTER의 이해와 활용방법_Wh oracleBlOOM FILTER의 이해와 활용방법_Wh oracle
BlOOM FILTER의 이해와 활용방법_Wh oracle
 
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracle
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracleORACLE EXADATA HCC 압축방식 이해하기_Wh oracle
ORACLE EXADATA HCC 압축방식 이해하기_Wh oracle
 
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천
#2.SQL초보에서 Schema Objects까지_재직자/근로자환급/국비지원교육/IT실무교육/SQL기초교육/구로IT학원추천
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
 
Tungsten 을활용한 MySQL / Hadoop 동기화
Tungsten 을활용한 MySQL / Hadoop 동기화Tungsten 을활용한 MySQL / Hadoop 동기화
Tungsten 을활용한 MySQL / Hadoop 동기화
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning
 
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracleSQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
SQL 튜닝에 Dictionary View 활용하기 Part2_Wh oracle
 
Federated Engine 실무적용사례
Federated Engine 실무적용사례Federated Engine 실무적용사례
Federated Engine 실무적용사례
 
(스프링JDBC와 Spring Data JPA비교)Spring JDBC와 JPA를 간단한 CRUD 예제로 만들면서 비교해보자.
(스프링JDBC와 Spring Data JPA비교)Spring JDBC와 JPA를 간단한 CRUD 예제로  만들면서 비교해보자.(스프링JDBC와 Spring Data JPA비교)Spring JDBC와 JPA를 간단한 CRUD 예제로  만들면서 비교해보자.
(스프링JDBC와 Spring Data JPA비교)Spring JDBC와 JPA를 간단한 CRUD 예제로 만들면서 비교해보자.
 
MySQL GTID 시작하기
MySQL GTID 시작하기MySQL GTID 시작하기
MySQL GTID 시작하기
 
SQL PlAN MANAGEMENT 활용_Wh oracle
SQL PlAN MANAGEMENT 활용_Wh oracleSQL PlAN MANAGEMENT 활용_Wh oracle
SQL PlAN MANAGEMENT 활용_Wh oracle
 
redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바redis 소개자료 - 네오클로바
redis 소개자료 - 네오클로바
 
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...
오라클 커서(Cursor) 개념 및 오라클 메모리 구조_PL/SQL,오라클커서강좌,SGA, PGA, UGA, Shared Pool, Sha...
 
Commit Wait Class 대기시간 감소 방안_Wh oracle
Commit Wait Class 대기시간 감소 방안_Wh oracleCommit Wait Class 대기시간 감소 방안_Wh oracle
Commit Wait Class 대기시간 감소 방안_Wh oracle
 
OracleHistory3
OracleHistory3OracleHistory3
OracleHistory3
 
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#20.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQL
 
대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle
 
SSD 개념 및 활용_Wh oracle
SSD 개념 및 활용_Wh oracleSSD 개념 및 활용_Wh oracle
SSD 개념 및 활용_Wh oracle
 
MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용MySQL 상태 메시지 분석 및 활용
MySQL 상태 메시지 분석 및 활용
 

Similar a 제1회 Tech Net Sql Server 2005 T Sql Enhancements

실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!Devgear
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQLJAEGEUN YU
 
04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)Hankyo
 
생체 광학 데이터 분석 AI 경진대회 1위 수상작
생체 광학 데이터 분석 AI 경진대회 1위 수상작생체 광학 데이터 분석 AI 경진대회 1위 수상작
생체 광학 데이터 분석 AI 경진대회 1위 수상작DACON AI 데이콘
 
02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)Hankyo
 
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)탑크리에듀(구로디지털단지역3번출구 2분거리)
 
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4Seok-joon Yun
 
Programming java day2
Programming java day2Programming java day2
Programming java day2Jaehoonyam
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Javajigi Jaesung
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴Devgear
 
MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바NeoClova
 
The Cucumber for Java
The Cucumber for JavaThe Cucumber for Java
The Cucumber for JavaJonghwa Lee
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124한 경만
 
파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄SeongHyun Ahn
 
My sql tde kr_v1.0
My sql tde kr_v1.0My sql tde kr_v1.0
My sql tde kr_v1.0Sumi Ryu
 
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3Seok-joon Yun
 

Similar a 제1회 Tech Net Sql Server 2005 T Sql Enhancements (20)

실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!
 
테스트
테스트테스트
테스트
 
Fundamentals of Oracle SQL
Fundamentals of Oracle SQLFundamentals of Oracle SQL
Fundamentals of Oracle SQL
 
AWS DevDay 실습 가이드 - 콘테이너
AWS DevDay 실습 가이드 - 콘테이너AWS DevDay 실습 가이드 - 콘테이너
AWS DevDay 실습 가이드 - 콘테이너
 
04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)
 
생체 광학 데이터 분석 AI 경진대회 1위 수상작
생체 광학 데이터 분석 AI 경진대회 1위 수상작생체 광학 데이터 분석 AI 경진대회 1위 수상작
생체 광학 데이터 분석 AI 경진대회 1위 수상작
 
02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)02.실행환경 실습교재(데이터처리)
02.실행환경 실습교재(데이터처리)
 
Oracle History #9
Oracle History #9Oracle History #9
Oracle History #9
 
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(IT실무교육/국비지원교육/자바/스프링교육추천)#15.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
 
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
[2015 07-06-윤석준] Oracle 성능 최적화 및 품질 고도화 4
 
Programming java day2
Programming java day2Programming java day2
Programming java day2
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
 
MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바
 
The Cucumber for Java
The Cucumber for JavaThe Cucumber for Java
The Cucumber for Java
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124
 
파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄파이썬 데이터베이스 연결 1탄
파이썬 데이터베이스 연결 1탄
 
My sql tde kr_v1.0
My sql tde kr_v1.0My sql tde kr_v1.0
My sql tde kr_v1.0
 
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
[2015-06-26] Oracle 성능 최적화 및 품질 고도화 3
 

제1회 Tech Net Sql Server 2005 T Sql Enhancements

  • 1. Hands-On Lab 실습 메뉴얼 SQL Server™ 2005: T-SQL Enhancements 실습
  • 2. 2 목 차 실습 메뉴얼....................................................................................................................................................................1 SQL Server™ 2005:....................................................................................................................................................1 T-SQL Enhancements 실습........................................................................................................................................1 연습 0 실습 설정 ..................................................................................................................................................................3 Chapter 1 -연습 1: varchar(max) ..............................................................................................................................4 Chapter 1 -연습 2: 행 오버플로우 지원 ................................................................................................................5 Chapter 1 -연습 3: Snaptshot isolation level ............................................................................................................6 Chapter 1 -연습 4: 예외 처리...................................................................................................................................8 Chapter 2 -연습 1: TOP 연산자 기능 향상...........................................................................................................11 Chapter 2 -연습 2: 문자셋 지원.............................................................................................................................13 Chapter 2 -연습 3: 파티션(분할) 테이블 구성 및 성능테스트...........................................................................15 Chapter 3 -연습 1: DDL 트리거를 이용한 로깅 및 테이블 변경 방지.............................................................18 Chapter 3 -연습 2: DDL 트리거를 이용한 MASTER DATABASE 백업자동화..............................................20 Chapter 3 -연습 3: XML 향상.................................................................................................................................23 Chapter 4 -연습 1: RANKING 함수들을 이용해서, 쉽게 순위 구하기.............................................................24 Chapter 4 -연습 2: PIVOT & UNPIVOT.................................................................................................................26 Chapter 4 -연습 3: 시스템 정보 보기....................................................................................................................27 Chapter 4 -연습 4: DMV..........................................................................................................................................29 Chapter 5 -연습 1: 원격쿼리 향상..........................................................................................................................32 Chapter 5 -연습 2: tablesample...............................................................................................................................33 Chapter 5 -연습 3: cascade (연계참조 무결성).....................................................................................................34 Chapter 5 -연습 4: OUTPUT..................................................................................................................................36 Chapter 6 -연습 1: CTE...........................................................................................................................................38 Chapter 6 -연습 2: Apply 연산자...........................................................................................................................40 Chapter 6 -연습 3: 쿼리 힌트.................................................................................................................................43 www.SQLAcademy.com
  • 3. 3 SQL Server 2005 T-SQL Enhancements 목표 이 실습을 끝마치고 나면, 여러분은 다음과 같은 작업을 하실 수 있습니다:  SQL Server 2005 에서의 향상된 T-SQL 기능에 대해 이해할 수 있다.  SQL Server 2005 에서의 향상된 T-SQL 기능을 사용하는 법을 직접 습득하여 실무에서 바로 적용할 수 있다. Note 이 실습은 이 장의 개념에 초점을 맞추어 작성되었습니다. 따라서 이 실습은 마이크로소프트 보안 권고사항에 정확히 부합하지 않을 수 있습니다. 시나리오 SQL Server 2005 는 전통적인 데이터베이스 기반에 개발환경이 통합된 플랫폼으로 SQL Server 2005 T-SQL 엔진의 변화에 대해서 이해하고 있어야만 개발과 유지보수 시 최상의 프로젝트를 진행할 수 있습니다. 이 번 강좌에서는 가장 필요하고 실무에서 자주 사용되는 혹은 되어야 할 SQL Server 2005 T-SQL 기능과 사 용법에 대해서 설명할 것이다. 선수조건 이번 실습을 시작하기 전에 여러분은 다음과 같은 지식을 갖추고 있어야 한다:  기본적인 윈도우 운영 환경  기본적인 T-SQL 사용 경험  SQL Server 2000 혹은 2005 개발 경험 예상 소요시간: 210 분 연습 0 실습 설정 실습 환경 설정 www.SQLAcademy.com
  • 4. 4 - SQL Server 2005 (Enterprise or Developer or Evaluation) Edition - 실습을 위한 예제용 데이터베이스인 Adventureworks 가 있어야 한다. 실습 시 설치하도록 한다. 설치 되어 있지 않다면 아래 주소에서 “AdventureworksDBCI.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)) GO INSERT 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_01 SELECT SUBSTRING(VMEMO,10000,10) FROM DBO.VARMAX_01 V Task 2: text 컬럼에서의 substring 함수사용을 확인한다. .1 예제를 위한 테이블생성과 데이터를 입력한다 CREATE TABLE DBO.TEXT_01 (TID INT, TMEMO NTEXT) GO INSERT INTO DBO.TEXT_01(TID,TMEMO) VALUES(1,REPLICATE(N'Guidelines and www.SQLAcademy.com
  • 5. 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_01 SELECT SUBSTRING(TMEMO,10000,10) FROM DBO.TEXT_01 T Task 3: VARCHAR(MAX) 의기본속성을확인한다 .1 예제를 위한 테이블생성과 데이터를 입력한다 CREATE TABLE DBO.VARMAX_02 (VID INT, VMEMO VARCHAR(MAX)) GO SELECT 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 G Task 2: 페이지크기의 한계인 8060 bytes 한계를 넘는 데이터가 잘 입력되는지 확인한다. .1 페이지크기의 한계인 8060 한계를 넘는 데이터가 잘 입력되는지 확인한다 INSERT INTO DBO.ROWOVER(RID, R1, R2) VALUES(1, REPLICATE('A',5000), REPLICATE('A',5000)) GO G 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') www.SQLAcademy.com
  • 6. 6 SELECT * 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_ON GO .2 DB 옵션을 ALLOW_SNAPSHOT_ISOLATION 으로 설정한다. 기본값은 OFF 이다 ALTER DATABASE SNAPSHOT_ON SET ALLOW_SNAPSHOT_ISOLATION ON GO .3 옵션변경이 잘 되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다 USE SNAPSHOT_ON GO DBCC USEROPTIONS GO SELECT NAME, snapshot_isolation_state, is_read_committed_snapshot_on FROM sys.databases WHERE NAME = 'SNAPSHOT_ON' .4 다음을 수행하여 트랜잭션을 시작한다. 현재 연결을 SESSION1 이라 명명한다 --SESSION1) USE SNAPSHOT_ON GO CREATE TABLE DBO.SNAP_01 (SID INT, SNAME CHAR(10)) www.SQLAcademy.com
  • 7. 7 GO INSERT INTO DBO.SNAP_01(SID,SNAME) VALUES(1,'JONES') GO BEGIN TRAN UPDATE DBO.SNAP_01 SET SNAME = 'NANCY' .5 트랜잭션이 잘 시작되었는지 확인한다. 다음 두 방법을 이용해 확인할 수 있다 --SESSION1) SELECT * FROM sys.dm_tran_active_snapshot_database_transactions SELECT @@TRANCOUNT .6 새로운 쿼리실행창을 열어서 다음 문장을 실행한다. BEFORE IMAGE 즉, 트랜잭션이 실행되기 전의 스냅샷을 출력하는 것을 확인한다 --SESSION2) SET TRANSACTION ISOLATION LEVEL SNAPSHOT GO SELECT * FROM DBO.SNAP_01 .7 트랜잭션을 시작했던 쿼리실행창에서 다음을 실행한다 --SESSION1) ROLLBACK .8 SESSION2 쿼리실행창을 닫는다 .9 같은 과정을 스냅샷옵션 변경 없이 실행해 본다. 잠금으로 인해 blocked 되는 것을 확인할 수 있다 www.SQLAcademy.com
  • 8. 8 Chapter 1 -연습 4: 예외 처리 시나리오 SQL Server 2005 에서 새롭게 지원하는 예외처리 기능인 try… catch 문을 실행하는 방법을 알아본다. . Task 1: 단순오류 발생 시 예외처리프로세스를 알아본다 .1 예제를위한테이블과데이터를준비한다 CREATE TABLE DBO.TRYCATCH ( TID TINYINT, TNAME CHAR(10)) GO INSERT INTO DBO.TRYCATCH(TID,TNAME) VALUES(1,'JONES') GO .2 오류가 발생하도록 INSERT 문장을 실행하고, 예외처리블록을 지정하여 오류를 출력하도록 한다. 어떤 오류가 발생하는지 확인하도록 한다. 아래 명령은 일괄처리로 실행되어야 하므로, 모든 영역을 선택해 서 한번에 실행하도록 한다 DECLARE @TRANCNT TINYINT BEGIN TRANSACTION BEGIN TRY INSERT INTO DBO.TRYCATCH(TID,TNAME) VALUES (300, 'INDIANA') WAITFOR DELAY '00:00:05' SET @TRANCNT = @@TRANCOUNT SELECT COUNT(*) AS '총갯수' FROM TRYCATCH COMMIT END TRY BEGIN 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 오류발생프로시저명 www.SQLAcademy.com
  • 9. 9 ROLLBACK END CATCH SELECT @TRANCNT AS '@@TCount' GO G Task 2: DEADLOCK 발생 시 예외처리하기 .1 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되, SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다 --SESSION1) BEGIN TRANSACTION BEGIN TRY INSERT DBO.TRYCATCH VALUES (10, 'AAAA') WAITFOR DELAY '00:00:05' SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH COMMIT END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACK END CATCH SELECT @@TRANCOUNT AS '트랜잭션중첩수' --SESSION2) BEGIN TRANSACTION BEGIN TRY INSERT DBO.TRYCATCH VALUES (20, 'BBBB') WAITFOR DELAY '00:00:05' SELECT COUNT(*) AS '총갯수' FROM DBO.TRYCATCH COMMIT END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS '오류번호' ROLLBACK END CATCH SELECT @@TRANCOUNT AS '트랜잭션중첩수' .2 어떤 오류가 발생되었는지 확인한다. 오류는 발생하지 않았고, 트랜잭션은 실행되었다 --SESSION1) 에서 결과창의 데이터를 확인만 한다 .3 SESSION1 에서 실행한 트랜잭션이 제대로 COMMIT 되었는지 확인한다. COMMIT 되었다 --SESSION1) SELECT * FROM DBO.TRYCATCH .4 SESSION2 에는 어떤 오류가 발생되었는지 확인한다. 교착상태오류(1205 번)가 발생했고, 트랜잭션은 ROLLBACK 되었다 --SESSION2) 에서 결과창의 데이터를 확인만 한다 .5 --SESSION1) www.SQLAcademy.com
  • 10. 10 Task 3: DEADLOCK 발생 시 트랜잭션 재시도하기, 이제 교착상태가 발생하면 ROLLBACK 하고 종료하는 것이 아닌, 트랜잭션을 재시도하도록 루틴을 작성해보자. 이 루틴은 2005 에서 데이 터일관성을 위해 deadlock 처리를 어떻게 할 수 있는지에 대한 좋은 예가 된다 .1 교착상태를 일으키는 문장을 실행한다. 이때 SESSION1, SESSION2 두 연결 모두에서 실행하되, SESSION1 에서 먼저 실행한 후 SESSION2 에서는 5 초 이내에 실행해야 한다 --SESSION1) DECLARE @Tries tinyint SET @Tries = 1 WHILE @Tries <= 3 BEGIN 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 CATCH END --SESSION2) DECLARE @Tries tinyint SET @Tries = 1 WHILE @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 CATCH END .2 SESSION2 에서 교착상태가 발생되었을 때 어떻게 실행되었는지 확인한다. 재시도 횟수를 늘려서 교착 상태 발생 시에도 트랜잭션의 일관성을 보장하도록 할 수 있다 SELECT * FROM DBO.TRYCATCH www.SQLAcademy.com
  • 11. 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 INT SELECT @A=COUNT(EMPLOYEEID) FROM NORTHWIND.dbo.Employees SELECT TOP(@A-2) * FROM NORTHWIND.dbo.Employees ORDER BY EMPLOYEEID DESC GO .2 1 번과 같은 로직을 사용해서 2005 환경에서 실행한다. 2005 에는 NORTHWIND 데이터베이스가 없으므 로 ADVENTUREWORKS 데이터베이스의 PERSON.ADDRESS 테이블을 대신 이용하도록 한다. 오류 없 이 잘 실행되는 것을 확인할 수 있다 DECLARE @A INT SELECT @A=COUNT(ADDRESSID) FROM ADVENTUREWORKS.PERSON.ADDRESS SELECT TOP(@A-2) * FROM ADVENTUREWORKS.PERSON.ADDRESS ORDER BY ADDRESSID DESC GO G Task 2: UPDATE 에서 TOP 사용하기 www.SQLAcademy.com
  • 12. 12 .1 SQL Server 2000 환경에서 TOP 을이용한 UPDATE 를실행해본다. 지원하지않는기능이므로, 오류가발생 하는것을확인할수있다 UPDATE TOP (2) NORTHWIND.DBO.EMPLOYEES SET EMPLOYEEID = 276 WHERE EMPLOYEEID IN (1,2,3,4,5) GO .2 SQL Server 2005 환경에서 TOP 을 이용한 UPDATE 를 실행한다. 잘 실행된다 BEGIN TRAN UPDATE TOP (2) ADVENTUREWORKS.PERSON.ADDRESS SET AddressLine2 = 'Daehan Bldg. 3th' WHERE ADDRESSID IN (1,2,3,4,5) .3 변경된 데이터를 확인한다. 그러나 실제 변경된 데이터는 임의의 데이터이며 ,어떤 데이터를 변경할 것인지, 우리는 결정할 수 없다 SELECT * FROM ADVENTUREWORKS.PERSON.ADDRESS WHERE ADDRESSID IN (1,2,3,4,5) .4 작업을 취소한다 ROLLBACK TRANSACTION GO .5 우리가 원하는, 즉 의미 있는 데이터를 변경하기 위해서는 다음과 같은 로직을 사용해야 한다. 여기서 는 주소번호가 가장 큰 2 사람 만을 변경하도록 예제를 만들었다 USE ADVENTUREWORKS GO UPDATE PERSON.ADDRESS SET AddressLine2 = 'Daehan Bldg. 3th' FROM (SELECT TOP 2 ADDRESSID AS AID FROM PERSON.ADDRESS ORDER BY ADDRESSID DESC ) AS A WHERE ADDRESSID = A.AID GO .6 실행결과를 확인한다 SELECT TOP 10 * FROM ADVENTUREWORKS.PERSON.ADDRESS ORDER BY ADDRESSID DESC D Task 3: DELETE 에서 TOP 사용하기 .1 DELETE 를 이용해 삭제할 수 있다. 아래 문장을 실행해서 확인한다. 잘 실행된다 BEGIN TRAN DELETE TOP (20) FROM Purchasing.PurchaseOrderDetail WHERE DueDate < '20020701' .2 작업을 취소한다 ROLLBACK TRAN www.SQLAcademy.com
  • 13. 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 TEST GO USE TEST GO .2 테이블을 생성하되, 문자 컬럼을 일반 유니코드형식으로 작성한다 CREATE TABLE DBO.KOR (KID INT, KNAME VARCHAR(50) COLLATE KOREAN_WANSUNG_CI_AS) GO .3 생성한 테이블의 문자열에 한글고어문자를 입력하고, 결과를 확인한다. 정확한 데이터가 입력되어 있 지 않은 것을 확인할 수 있다 www.SQLAcademy.com
  • 14. 14 INSERT INTO DBO.KOR(KID,KNAME) VALUES(1, 'ᆟ') GO SELECT * FROM KOR SELECT UNICODE(KNAME) FROM DBO.KOR .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) GO SELECT KID, CAST(KNAME AS NVARCHAR(50)) COLLATE KOREAN_90_CI_AS FROM DBO.KOR2 SELECT UNICODE(KNAME) FROM DBO.KOR2 .6 컬럼 생성과 입력, 출력 시 모두 KOREAN_90_CI_AS 형식을 설정하지 않으면, 표현이 불가능하다. 이를 조합해서 실습해보자... --자체실습... www.SQLAcademy.com
  • 15. 15 Chapter 2 -연습 3: 파티션(분할) 테이블 구성 및 성능테스트 시나리오 SQL Server 2005 에서 지원하는 파티션테이블에 대한 개념과 사용법을 알아본다. . Task 1: 실습을 위한 데이터베이스 준비. .1 4 개의 추가 데이터파일과 각각의 파일이 포함되는 파일그룹으로 구성되도록 데이터베이스를 생성한 다 CREATE DATABASE PARTITIONTEST GO ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG1 GO ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG2 GO ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG3 GO ALTER DATABASE PARTITIONTEST ADD FILEGROUP FG4 GO ALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE11',FILENAME='C:CFILE11.NDF',SIZE=10) TO FILEGROUP FG1 GO ALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE22',FILENAME='C:DFILE22.NDF',SIZE=10) TO FILEGROUP FG2 GO ALTER DATABASE PARTITIONTEST ADD FILE(NAME='FILE33',FILENAME='C:EFILE33.NDF',SIZE=10) TO FILEGROUP FG3 GO ALTER DATABASE PARTITIONTEST ADD www.SQLAcademy.com
  • 16. 16 FILE(NAME='FILE44',FILENAME='C:FFILE44.NDF',SIZE=10) TO FILEGROUP FG4 GO G Task 2: 파티션구성, 파티션함수생성->파티션스킴생성->테이블생성. .1 날짜를 기준으로 4 부분으로 분할 입력하게 해 주는, 파티션함수(function)를 생성한다 USE PARTITIONTEST GO CREATE PARTITION FUNCTION DBO.DateFn(smalldatetime) AS RANGE RIGHT FOR VALUES ('20000101', '20030101','20060101') -- 오른쪽값 을기준값으로줌 GO .2 생성한 함수의 날짜범위에 파일그룹이 할당되도록, 파티션스킴(scheme)을 작성한다 CREATE PARTITION SCHEME DBO.DateScheme AS PARTITION DateFn TO (fg1,fg2,fg3,fg4) GO G 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 INT SET @NO=0 WHILE @NO < 1000 BEGIN 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+1 END SET NOCOUNT ON GO .3 입력된 데이터를 확인한다 SELECT COUNT(*) FROM DBO.CardAppr SELECT max(apprdate) FROM DBO.CardAppr SELECT * FROM DBO.CardAppr order by cid www.SQLAcademy.com
  • 17. 17 .4 파티션 범위를 확인한다 SELECT $partition.DateFn(ApprDate) AS 파티션번호 , min(ApprDate) AS MinDate , max(ApprDate) AS MaxDate , 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.partitions WHERE object_id = OBJECT_ID('CardAppr') ORDER BY partition_number, index_id GO G Task 4: 실제로 특정날짜만을 질의하는 쿼리를 실행했을 때, 해당파티션만을 검색하는지 확인한 다. .1 인덱스를 생성한다. CREATE clustered INDEX ix_CardAppr_ApprDate ON DBO.CardAppr (ApprDate, cid) ON DateScheme(ApprDate) GO .2 실행계획을 확인한다. StmtText 열의 끝부분을 확인하면 된다 SET STATISTICS PROFILE ON GO SELECT * FROM DBO.CardAppr WHERE ApprDate ='20030101' SET STATISTICS PROFILE OFF www.SQLAcademy.com
  • 18. 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_CREATETAB ON DATABASE FOR CREATE_TABLE AS INSERT INTO DBO.DDLLOG VALUES( EVENTDATA()) --DDL 트리거를실행하는이벤트에대한정보는EVENTDATA 함수를사용하여캡처할수있다 --이함수는XML 값을반환한다 GO .3 실제로 테이블을 생성해 본다 CREATE TABLE DBO.SSS( SID INT PRIMARY KEY IDENTITY, SNAME VARCHAR(MAX)) GO www.SQLAcademy.com
  • 19. 19 .4 로깅이 잘 되어 있는 지 확인한다. 결과값(XML)을 클릭하면 XML 데이터를 확인할 수 있다. 어떤 정보 가 있는 지 확인해 본다 SELECT * FROM DBO.DDLLOG Task 2: 테이블 생성내역을 문자열기록으로 남기기. .1 기록을 남기는 작업을 포함하는 DDL 트리거를 작성한다 CREATE TRIGGER TRG_CREATETAB2 ON 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 )’ C Task 3: 특정 테이블에 대한 삭제작업을 금지시키기. .1 삭제대상이 될 테이블을 작성한다 CREATE TABLE DBO.ZZZ(ZID INT, ZNAME VARCHAR(10)) GO .2 DROP_TABLE 이벤트에 대하여, 'ZZZ' 테이블이라면 롤백하는 DDL 트리거를 작성한다 CREATE TRIGGER TRG_PREVENT_DROPTTT ON DATABASE FOR DROP_TABLE AS DECLARE @TAB TABLE( TNAME VARCHAR(MAX)) INSERT @TAB SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText) [1]','NVARCHAR(MAX)') -- SELECT * FROM @TAB IF EXISTS(SELECT * FROM @TAB WHERE TNAME LIKE '%ZZZ%') BEGIN ROLLBACK END GO .3 DROP TABLE 문장을 각각 조건에 없는 테이블(SSS)와, 조건에 해당하는 테이블(ZZZ)에 대하여 실행 한다 DROP TABLE DBO.SSS --> 트리거발생되지않음 GO www.SQLAcademy.com
  • 20. 20 DROP TABLE DBO.ZZZ --> 트리거발생됨 GO .4 ROLLBACK 처리가 되었는지 확인한다 SELECT * FROM DBO.SSS --> 삭제됨 SELECT * FROM DBO.ZZZ --> 롤백되어삭제되지않았음 .5 데이터베이스 수준의 DDL 트리거를 삭제하는 방법은 다음과 같다 DROP TRIGGER TRG_PREVENT_DROPTTT ON DATABASE GO Chapter 3 -연습 2: DDL 트리거를 이용한 MASTER DATABASE 백 업자동화 시나리오 1. 사용자정의 메시지를 생성한다. 2. master 데이터베이스에 변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다. 3. master 데이터베이스를 백업하는 job 을 생성한다. 4. 메시지이벤트가 발생되면 자동으로 백업 job 을 수행하도록, 경고를 작성한다. 5. 실제로 master 데이터베이스 변경작업을 시도하여, 백업이 되는지 확인한다. . Task 1: 사용자정의 메시지를 생성한다. .1 master 데이터베이스에서 작업한다 Use Master GO .2 아래명령을 실행하여 메시지를 생성한다. 반드시 영문 먼저 생성해야, 한글메시지도 작성된다는 것에 유의하자 EXEC sp_addmessage 50001, 10, N'Master Database has changed' , 'us_english', www.SQLAcademy.com
  • 21. 21 'TRUE', 'REPLACE' GO EXEC sp_addmessage 50001, 10, N'마스터데이터베이스내용이변경되었습니다' , 'korean', 'TRUE', 'REPLACE' GO G Task 2: master 데이터베이스에 변경이 감지되면, 이 메시지를 발생하도록 트리거를 작성한다. .1 트리거 작성 Create trigger Trg_Master_BackupAutomation_Server on all SERVER for CREATE_DATABASE , ALTER_DATABASE, DROP_DATABASE , DDL_LOGIN_EVENTS, DDL_GDR_SERVER_EVENTS, DDL_AUTHORIZATION_SERVER_EVENTS , DDL_ENDPOINT_EVENTS as Raiserror (50001, 10, 1) with log GO G 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:TSQLMaster.bak' with Init, Format GO .vi “구문분석” 버튼을 누른다. 이때 오류가 없어야 한다. .vii “고급/성공한경우동작” 항목은 “성공보고와함께작업종료” 를 선택한다. .viii“확인” 버튼을 누른다. .d “확인” 버튼을 누른다. . Task 4: 메시지이벤트가 발생되면 자동으로 백업 job 을 수행하도록, 경고를 작성한다. www.SQLAcademy.com
  • 22. 22 .1 SSMS 의 개체탐색기의 “SQL Server 에이전트/경고” 항목에서 마우스 오른쪽버튼을 클릭하고, “새경고 ” 버튼을 누른다. 창이 열리면 다음을 실행한다 .a “일반/이름” 항목에 “Master 데이터베이스백업자동화”를 입력한다. .b “일반/유형” 항목에서 “SQL Server 이벤트경고” 를 선택한다. .c “일반/데이터베이스이름” 항목에서 “Master” 를 선택한다. .d “일반/경고발생기준” 항목은 “오류번호” 옵션을 선택하고, “50001”을 입력한다. .e “응답/작업실행” 체크박스에 체크표시한다. .f “응답/작업실행”의 목록에서, 사전에 작업을 생성해 둔, “Master 데이터베이스백업”을 선택한다. .g “확인” 버튼을 누른다. . Task 5: 실제로 master 데이터베이스변경작업을시도하여, 백업이되는지확인한다 .1 다음 작업들을 실행해서, 실제로 Master 데이터베이스에 대한 자동백업이 수행되는지 확인한다 .a SSMS 의 쿼리실행창에서 다음 명령을 수행하고, 탐색기의 ‘D:TSQL” 폴더 내에 “Master.bak” 가 생성되었는지 각각의 명령에 대해 확인한다. CREATE DATABASE TRG GO DROP DATABASE TRG GO .b 역시 다음 명령을 실행하고, 탐색기의 ‘D:TSQL” 폴더 내에 “Master.bak” 가 생성되었는지 각각의 명령에 대해 확인한다. CREATE LOGIN AAA WITH PASSWORD = 'Pa$$w0rd' GO DROP LOGIN AAA GO .2 서버 수준의 DDL 트리거를 삭제하는 방법은 다음과 같다 DROP TRIGGER Trg_Master_BackupAutomation_Server on all SERVER GO www.SQLAcademy.com
  • 23. 23 Chapter 3 -연습 3: XML 향상 시나리오 SQL Server 2005 에서 새롭게 지원하는 XML 사용법을 알아본다. . Task 1: XML 형식으로 데이터를 출력하여, 응용프로그램으로 반환할 수 있다. .1 기존에 저장되어 있는 NON XML 컬럼을 XML 로 출력 가능함. 이때 자동으로 타입변경가능 USE ADVENTUREWORKS GO SELECT ContactID, FirstName, LastName, Phone FROM Person.Contact ORDER BY ContactID FOR XML AUTO, TYPE T Task 2: 출력(SELECT) 뿐 아니라, 입력과 수정에도 사용 가능하다는 것을 확인한다. .1 XML 형식을 갖는 컬럼을 포함하여 테이블을 생성하고 데이터를 입력한다 CREATE TABLE DBO.T1(intCol int, XmlCol xml) GO INSERT INTO DBO.T1 VALUES(1, '<Root><ProductDescription ProductModelID="1" /></Root>') GO www.SQLAcademy.com
  • 24. 24 .2 XML 형식 컬럼을 조회해서, 다른 테이블의 XML 컬럼에 입력 가능하다 CREATE TABLE DBO.T2(XmlCol xml) GO INSERT INTO DBO.T2(XmlCol) SELECT (SELECT XmlCol.query('/Root') FROM DBO.T1 FOR XML AUTO,TYPE) GO .3 결과를 확인한다 SELECT * FROM DBO.T2 Chapter 4 -연습 1: RANKING 함수들을 이용해서, 쉽게 순위 구하 기 시나리오 SQL Server 2005 에서 새롭게 지원하는 순위함수들의 의미와 사용법을 알아본다. . Task 1: RANK() 함수 기능이해 .1 아래 문장을 실행해서 RANK() 함수의 기본기능을 이해한다. 결과를 보면 ListPrice 값이 4.99 인 예에서 동점도 랭킹에 포함되고 있음을 알 수 있다 USE ADVENTUREWORKS GO SELECT P.Name Product, P.ListPrice, PSC.Name Category, RANK() OVER(ORDER BY P.ListPrice ) AS PriceRank FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID ORDER BY 2, 4 .2 아래 문장을 실행해서 PARTITION BY 키워드를 사용했을 때의 기능을 이해한다. 결과를 보면 Category 값이 Gloves, handlesbars 인 예에서 동점도 랭킹에 포함되고 있음을 알 수 있다 www.SQLAcademy.com
  • 25. 25 SELECT P.Name Product, P.ListPrice, PSC.Name Category, RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRank FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID ORDER BY 3, 4 Task 2: DENSE_RANK () 함수 기능이해 .1 아래 문장을 실행해서 DENSE_RANK() 함수의 기능을 이해한다. 결과를 보면 Category 값이 Gloves, handlesbars 인 예에서 동점과 상관없이 점수 자체로만 랭킹하고 있음을 알 수 있다 SELECT P.Name Product, P.ListPrice, PSC.Name Category, DENSE_RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRank FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID ORDER BY 3,4 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.ListPrice FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN Production.ProductCategory PC ON PSC.ProductCategoryID = PC.ProductCategoryID ORDER BY 2,1 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.ListPrice FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN Production.ProductCategory PC ON PSC.ProductCategoryID = PC.ProductCategoryID ORDER BY 2,4 www.SQLAcademy.com
  • 26. 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)) GO INSERT 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') GO .2 2005 에서의 설계-->설계단순화 및 저장공간 감소 CREATE TABLE MEMBER2 (MID INT IDENTITY PRIMARY KEY, MNAME NVARCHAR(50), FAVORITE NVARCHAR(20)) www.SQLAcademy.com
  • 27. 27 GO 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'영화') INSERT INTO MEMBER2(MNAME,FAVORITE) VALUES( N'이순신', N'뮤지컬') GO .3 관심분야종류를 파악한다 SELECT DISTINCT FAVORITE FROM DBO.MEMBER2 .4 필요한 관심분야 종류별로 회원 별 개수를 출력한다 SELECT * FROM DBO.MEMBER2 PIVOT (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.DATABASES .3 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다 SELECT * FROM SYS.TABLES ORDER BY NAME .4 도움말의 색인항목의 찾을 대상 textbox 에서 "SYS."을 입력한 후 나타나는 카탈로그뷰의 목록을 확인 한다 한Task 2: 일반적으로 사용할 수 있는 정보스키마뷰를 사용해 본다 .1 다음을 실행하면 데이터베이스 내의 모든 테이블과 뷰정보를 볼 수 있다 www.SQLAcademy.com
  • 28. 28 SELECT * FROM INFORMATION_SCHEMA.TABLES .2 다음을 실행하면 WHERE 절에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다 SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'ADDRESS' .3 도움말의 색인항목의 찾을대상 textbox 에서 "INFORMATION_" 을 입력한 후 나타나는 카탈로그뷰의 목록을 확인한다 확Task 3: 일반적으로 사용되는 호환성뷰를 사용해본다 .1 다음을 실행하면 데이터베이스 내의 모든 테이블정보를 볼 수 있다. SYS.OBJECTS 와 비교해보자. ID 컬럼명 등이 다르고 출력하는 속성목록이 다른 것을 확인할 수 있다 SELECT * FROM SYSOBJECTS .2 다음을 실행하면 현재 실행계획캐쉬에 저장되어 있는 명령들을 확인할 수 있다 SELECT * FROM SYS.SYSCACHEOBJECTS .3 다음을 실행하면 WHERE 절 에서 지정한 테이블 내의 모든 컬럼정보를 볼 수 있다 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 h 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 h Task 5: 일반적으로 사용할 수 있는 시스템프로시저를 사용해본다 .1 다음을 실행하면 현재 인스턴스의 DB 버전과 OS 버전 등을 확인할 수 있다 EXEC DBO.XP_MSVER .2 다음을 실행하면 지정한 테이블의 제약정보를 확인할 수 있다 EXEC DBO.SP_HELPCONSTRAINT 'PERSON.ADDRESS' .3 다음을 실행하면 지정한 테이블의 컬럼정보를 확인할 수 있다 EXEC DBO.SP_COLUMNS 'ADDRESS', 'PERSON' www.SQLAcademy.com
  • 29. 29 Chapter 4 -연습 4: DMV 시나리오 SQL Server 2005 에서 추가로 지원하는 시스템정보(메타데이터) 추출 방법인 DMV 에 대해 종류와 의미를 알아본다. . Task 1: 실습준비 .1 아래 문장을 10 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다 SELECT * FROM Sales.SalesOrderDetail SELECT * FROM Sales.Individual .2 --2. 아래 문장을 50 번 정도 실행한다. 향후 실습에서 플랜정보를 보기 위함이다 SELECT * FROM PRODUCTION.CULTURE C Task 2: sys.dm_exec_query_stats 동적뷰를 질의하여, 리소스를 많이 차지하고 있는 상위쿼리를 확 인한다 .1 sys.dm_exec_query_stats 의 기본정보를 확인한다. SELECT * FROM SYS.dm_exec_query_stats .2 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_exec_query_stats" 을 입력하여, 이 뷰의 속성정보를 확인한다. total_worker_time,execution_count, total_physical_reads, last_physical_reads 등을 특히 확인한다 www.SQLAcademy.com
  • 30. 30 .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 qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ORDER 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, ((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 qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ORDER 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 qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st ORDER BY last_logical_reads DESC D Task 3: sys.dm_exec_cached_plans 동적뷰를 질의하여, 캐시된 플랜정보를 확인한다 .1 sys.dm_exec_cached_plans 의 기본정보를 확인한다. SELECT * FROM SYS.dm_exec_cached_plans .2 도움말의 색인항목의 찾을대상 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 cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st ORDER BY usecounts DESC, refcounts DESC .4 캐쉬된 플랜에 대한 메모리점유량 별 상위 100 개의 쿼리를 확인한다. 상위문장을 확인한다 www.SQLAcademy.com
  • 31. 31 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 st WHERE cacheobjtype = 'Compiled Plan' AND st.text not like '%sys%' ORDER BY 3 DESC, 5 DESC GO .5 아래를 각각 따로따로 여러번(5 번정도) 실행한 뒤, 위 4 번 문장을 다시한번 실행해본다. WHERE 을 사 용하지 않은 명령은 인덱스를 사용하지 못했으므로 50 PAGE, 사용한 명령은 인덱스를 사용했으므로 2 PAGE 만을 점유하고 있는 것을 알 수 있다 SELECT * FROM SALES.INDIVIDUAL SELECT * FROM SALES.INDIVIDUAL WHERE CUSTOMERID = 11000 Task 4: sys.dm_tran_database_transactions 동적뷰를 질의하여, 의미있는 트랜잭션 중에서 로그생 성수 기준 상위 트랜잭션을 확인한다 .1 sys.dm_tran_database_transactions 의기본정보를확인한다. SELECT * FROM SYS.dm_tran_database_transactions .2 도움말의 색인항목의 찾을대상 textbox 에서 "sys.dm_tran_database_transactions" 을 입력하여, 이 뷰의 속 성정보를 확인한다. .3 각기 다른 3 개의 쿼리실행창을 열어서 각각 다음 문장을 실행한다. 각각의 창은 SESSION1, SESSION2, SESSION3 으로 명명한다. --SESSION1) USE ADVENTUREWORKS GO BEGIN TRAN UPDATE PERSON.ADDRESS SET ADDRESSLINE2 = 'SEOUL' --SESSION2) USE ADVENTUREWORKS GO BEGIN TRAN UPDATE SALES.INDIVIDUAL SET CONTACTID = '11101' --SESSION3) USE ADVENTUREWORKS GO BEGIN TRAN UPDATE Sales.Customer SET MODIFIEDDATE = GETDATE() .4 현재 서버의 트랜잭션정보를, 아래 명령을 실행해서 확인한다 USE MASTER GO SELECT TRANSACTION_ID, DB_NAME(DATABASE_ID) AS DB명, DATABASE_TRANSACTION_BEGIN_TIME , CASE DATABASE_TRANSACTION_TYPE WHEN 1 THEN '읽기/쓰기' WHEN 2 THEN '읽기전 www.SQLAcademy.com
  • 32. 32 용' 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_transactions WHERE DATABASE_TRANSACTION_BEGIN_TIME IS NOT NULL ORDER BY [생성된로그행수] DESC D 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 .2 인스턴스명에서 오른쪽버튼을 클릭하고, "보고서/표준보고서/상위세션" 메뉴를 눌러서 읽기,쓰기항목 의 세션의 SPID 를 확인한다. 이는 메모리 사용량순위이지만 TEMPDB 사용량과도 어느 정도 일맥상통 하는 것을 확인할 수 있다 Chapter 5 -연습 1: 원격쿼리 향상 시나리오 SQL Server 2005 에서 향상된 원격쿼리의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다. . Task 1: EXECUTE .. AT 을 이용하여 쿼리하기 .1 먼저 원격서버를 등록한다. 만일 원격서버대상이 없는 경우에는 로컬서버에 있는 인스턴스를 등록하 도록 한다 .a 만일 로컬서버의 인스턴스명을 모르는 경우, 다음 명령을 실행해서 확인할 수 있다 SELECT * FROM SYS.SERVERS .b 만일 로컬서버의 인스턴스명을 확인했다면 다음을 실행하면 된다 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 일반적으로 사용하는 원격쿼리. 실행계획을 로컬서버가 생성하고 로컬에서 실행한다 www.SQLAcademy.com
  • 33. 33 SELECT * FROM CEYX2.NORTHWIND.DBO.EMPLOYEES WHERE EMPLOYEEID = 1 .b 일반적으로 사용하는 통과쿼리. 실행계획을 원격서버가 생성하고 원격에서 실행한다. 그러므로 정 확한 실행계획을 출력하지 않는다 --> !!!!!!!!! 로컬서버에 대해서는 실행되지 않으므로 위 문장은 실패한다. --> !!!!!!!!! 그러므로 다음 옵션을 설정하고 재실행하도록 한다. 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' GO EXECUTE ('SELECT * FROM NORTHWIND.DBO.EMPLOYEES WHERE EMPLOYEEID = ? ', 1) AT CEYX2 GO Chapter 5 -연습 2: tablesample 시나리오 SQL Server 2005 에서 향상된 원격쿼리의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다. . Task 1: tablesample 성능비교, 개발/유지보수 시 흔히 실행하는 top 과 2005 tablesample 과의 성능 비교 .1 데이터베이스 연결을 변경한다. 다음을 실행하면 된다 USE Adventureworks GO .2 다음 두 문장을 실행한다 SELECT * FROM SALES.INDIVIDUAL TABLESAMPLE (100 ROWS) GO SELECT TOP 100 * FROM SALES.INDIVIDUAL GO .3 2 번 단계의 두 문장을 영역으로 선택하고, SSMS 의 "예상실행계획보기" 단추를 누르거나, Ctrl+L 을 누 른다. 이때 출력되는 실행계획을 비교해 본다. 얼마나차이가나는지확인한다 얼Task 2 : 일정한 결과집합을 샘플링하고 싶다면 repeatable 옵션을 사용해야 한다. www.SQLAcademy.com
  • 34. 34 .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) 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)) GO INSERT 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') GO ALTER TABLE DBO.ACTOR ADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES MOVIE(MCODE) ON UPDATE CASCADE ON DELETE CASCADE GO INSERT 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') www.SQLAcademy.com
  • 35. 35 INSERT INTO DBO.ACTOR VALUES(5,'타마키히로시','B200') GO .2 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해 본다. CASCADE 옵션이 설정되어 있지 않았다면 RUNTIME 오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 변경된다 UPDATE DBO.MOVIE SET MCODE = 'H555' WHERE MCODE = 'B200' GO .3 잘 변경되었는지 확인한다 SELECT * FROM DBO.MOVIE SELECT * FROM DBO.ACTOR .4 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. CASCADE 옵션이 설정되어 있지 않았다면 RUNTIME 오류가 발생한다. 현재에는 설정되어 있으므로, 자식테이블 값도 동시에 삭제된다 DELETE FROM DBO.MOVIE WHERE MCODE = 'A100' GO .5 잘 삭제되었는지 확인한다 SELECT * FROM DBO.MOVIE SELECT * FROM DBO.ACTOR .6 두 테이블을 모두 삭제한다 DROP TABLE DBO.ACTOR GO DROP TABLE DBO.MOVIE GO G Task 2: cascade 의 SET NULL, SET DEFAULT 옵션이해 .1 위에서 실행했던 task1 의 1 번단계의 스크립트를 한번 더 실행한다. 다만 ALTER 문은 다음 문으로 대 체해서 실행하도록 한다 ALTER TABLE DBO.ACTOR ADD CONSTRAINT ACTOR_MCODE_FK FOREIGN KEY(MCODE) REFERENCES MOVIE(MCODE) ON UPDATE SET DEFAULT ON DELETE SET NULL GO .2 부모테이블의 MOCDE 값 'B200' 을 'H555' 로 변경해본다. 자식테이블값이 동시에 DEFAULT 값인 'A100' 으로 변경된다 UPDATE DBO.MOVIE SET MCODE = 'H555' WHERE MCODE = 'B200' GO .3 잘 변경되었는지 확인한다 SELECT * FROM DBO.MOVIE SELECT * FROM DBO.ACTOR .4 부모테이블의 MOCDE 값 'A100' 을 삭제해본다. 자식테이블값이 동시에 NULL 값으로 변경된다 DELETE FROM DBO.MOVIE WHERE MCODE = 'A100' GO .5 잘 삭제되었는지 확인한다 SELECT * FROM DBO.MOVIE SELECT * FROM DBO.ACTOR .6 두 테이블을 모두 삭제한다 DROP TABLE DBO.ACTOR www.SQLAcademy.com
  • 36. 36 GO DROP TABLE DBO.MOVIE GO Chapter 5 -연습 4: OUTPUT 시나리오 SQL Server 2005 에서 향상된 cascade 의 기능이 어떤 것들이 있는지 사용방법과 기능을 알아본다. . Task 1: 삭제정보를 반환하는 OUTPUT .1 예제를 위한 테이블을 생성한다 CREATE TABLE DBO.OUTPUT_01(OID INT,ONAME VARCHAR(20)) GO INSERT INTO DBO.OUTPUT_01 VALUES(1,'AAA') INSERT INTO DBO.OUTPUT_01 VALUES(2,'BBB') INSERT INTO DBO.OUTPUT_01 VALUES(3,'CCC') GO .2 삭제를 실행하되, 삭제된 행을 반환하도록 OUTPUT 절을 설정한다 DELETE DBO.OUTPUT_01 OUTPUT DELETED.* WHERE OID IN (1,2) GO .3 다음 문장은 SQL Server 2000 에서, OUTPUT 기능을 구현한 예이다 CREATE TRIGGER DBO.TRG_OUTPUT_01 ON OUTPUT_01 FOR DELETE AS www.SQLAcademy.com
  • 37. 37 SELECT * FROM DELETED GO DROP TRIGGER DBO.TRG_OUTPUT_01 GO G Task 2: 수정정보를 기록하도록 OUTPUT 사용 .1 수정정보를 기록할 테이블을 생성한다 CREATE TABLE DBO.OUTPUT_01_History ( HID INT IDENTITY, OID INT, BeforeONAME VARCHAR(20), AfterONAME VARCHAR(20), CHANGEDATE DATETIME ) GO .2 수정정보를 기록하도록 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' 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 GO .3 기록테이블에 수정 전후 데이터가 잘 입력되었는지 확인한다 SELECT * FROM DBO.OUTPUT_01_History www.SQLAcademy.com
  • 38. 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 B ON A.managerid = B.employeeid GROUP BY B.LoginID ORDER BY B.LoginID .2 CTE 를 사용한 쿼리문장을 실행한다. 그리고 실행계획을 확인한다. 직접 작성한 재귀쿼리와 차이가 있 는가 (없다) WITH CTETable(ManagerID) AS ( SELECT ManagerID FROM HumanResources.Employee AS e WHERE ManagerID IS NOT NULL www.SQLAcademy.com
  • 39. 39 ) SELECT B.LoginID, count(*) FROM CTETable JOIN HumanResources.Employee B ON B.EmployeeID = CTETable.ManagerID GROUP BY LoginID ORDER BY B.LoginID GO G Task 2: 테이블변수를 이용하여 재실행 .1 테이블변수를 사용하여 실행한다. 역시 실행계획을 살펴본다. 차이가 있는가 (테이블변수를 사용한 것 이 느리다) DECLARE @TAB TABLE(ManagerID INT) INSERT @TAB SELECT ManagerID FROM HumanResources.Employee AS e WHERE ManagerID IS NOT NULL SELECT B.LoginID, count(*) FROM @TAB A JOIN HumanResources.Employee B ON B.EmployeeID = A.ManagerID GROUP BY LoginID ORDER BY B.LoginID L Task 3: 상관관계 하위쿼리구현방법과 CTE 구현방법과의 성능비교, 역시 실행계획을 비교해본 다 (성능은 동일하다) .1 상관관계 하위쿼리로 작성 SELECT * FROM Sales.SalesOrderDetail A WHERE 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.SalesOrderDetail GROUP BY PRODUCTID ) SELECT * FROM Sales.SalesOrderDetail A WHERE 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) GO INSERT DBO.CarParts VALUES (1, 'Body', 'Door', 4) www.SQLAcademy.com
  • 40. 40 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) GO .2 CTE 를 이용해서 좀 더 단순하게 부품별 하위부품개수를 출력한다 WITH CarPartsCTE(SubPart, Qty) AS ( -- 기준테이블(anchor member) SELECT SubPart, Qty FROM DBO.CarParts WHERE Part = 'Body' UNION ALL -- 재귀테이블(recursive member) SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty FROM CarPartsCTE INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part WHERE CarParts.CarID = 1 ) SELECT SubPart, SUM(Qty) AS q FROM CarPartsCTE GROUP 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 AS BEGIN DECLARE @Result SMALLINT SELECT @Result = DATEDIFF(YY,@HIREDATE,GETDATE()) +1 RETURN @Result END GO SELECT *, DBO.FN_getYEAR(HIREDATE) 입사년차 FROM HUMANRESOURCES.EMPLOYEE ORDER BY EMPLOYEEID .2 CROSS APPLY 를이용해서출력하기. www.SQLAcademy.com
  • 41. 41 CREATE FUNCTION dbo.FN_getYEAR2(@HIREDATE AS SMALLDATETIME) RETURNS TABLE AS RETURN SELECT DATEDIFF(YY,@HIREDATE,GETDATE()) +1 AS 입사년차 GO SELECT * FROM HUMANRESOURCES.EMPLOYEE AS D CROSS APPLY DBO.FN_getYEAR2(D.HIREDATE) AS CA ORDER BY EMPLOYEEID .3 단일 데이터 출력에서는 작성도 쉽고, 결과와 실행과정이 같다. . 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 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) GO CREATE TABLE DBO.Departments ( deptid INT NOT NULL PRIMARY KEY, deptname VARCHAR(25) NOT NULL, deptmgrid INT NULL REFERENCES Employees ) GO INSERT 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) GO www.SQLAcademy.com
  • 42. 42 .2 직원수준을 반환하도록 함수를 작성한다 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 ) AS BEGIN 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 RETURN END GO .3 작성한 함수를 CROSS APPLY 연산자를 이용해 조인하여, 출력한다 SELECT * FROM DBO.Departments AS D CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST .4 CROSS APPLY 가 없었다면? --> 작성이복잡하고, 실행계획이다를수있으므로성능을측정해야한다. (숙 제) .5 OUTER APPLY, cross apply 에서적용되지않았던, 즉 deptmgrid 값이 null 인데이터도출력해준다 SELECT * FROM DBO.Departments AS D OUTER APPLY fn_getsubtree(D.deptmgrid) AS ST www.SQLAcademy.com
  • 43. 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)' www.SQLAcademy.com
  • 44. 44 GO .3 다시 한번 같은 명령을 실행하고, 실행계획을 살펴보자. 병렬처리가 되고, 비용이 줄어든 것을 확인할 수 있다 SELECT TOP 1000 * FROM Sales.INDIVIDUAL ORDER BY CONTACTID ASC .4 다음 카탈로그뷰를 이용해서 계획지침정보를 출력할 수 있다 SELECT * FROM sys.plan_guides .5 계획지침을 삭제한다. 비활성화 시에는 'DROP' 키워드 대신, 'DISABLE' 키워드를 사용하면 된다 EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'AD-HOC PLAN GUIDE 1' GO G Task 2: DATE_CORRELATION_OPTIMIZATION 옵션을 이용하여, 날짜관련 검색 최적화하기 .1 먼저 옵션을 설정한다 ALTER DATABASE Adventureworks SET DATE_CORRELATION_OPTIMIZATION ON GO .2 다음 문장을 실행하여, 데이터베이스의 DATE_CORRELATION_OPTIMIZATION 설정을 확인한다. 맨 뒷 열인'is_date_correlation_on' 열로 확인할 수 있다 SELECT * FROM SYS.DATABASES WHERE NAME = 'ADVENTUREWORKS' ' Task 3: 리컴파일 .1 다음은 저장프로시저 내의 특정 쿼리만을 리컴파일하는 예제이다 CREATE PROC DBO.UP_EMP @EID1 INT, @EID2 INT AS SELECT * FROM HUMANRESOURCES.EMPLOYEE WHERE EMPLOYEEID BETWEEN @EID1 AND @EID2 UNION ALL SELECT * FROM HUMANRESOURCES.EMPLOYEE WHERE EMPLOYEEID <> 500 OPTION ( RECOMPILE ) GO G Task 4: 쿼리계획을 저장해놓고, USE PLAN 을 이용하여 저장된 쿼리계획으로 실행하기 .1 먼저 프로파일러를 실행한다. 이때 다음 이벤트는 필수로 선택해야 한다 "stored procedure"의"RPC:Starting" "TSQL"의"SQL:Batchstarting" "Performance"의"Showplan XML" .2 실행할 쿼리는 다음과 같다. 실행하도록 한다 SELECT C.NAME, SUM(ORDERQTY) TOTAL www.SQLAcademy.com
  • 45. 45 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.NAME HAVING SUM(ORDERQTY) > 10 ORDER 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.NAME HAVING SUM(ORDERQTY) > 10 ORDER BY TOTAL DESC', @type = N'SQL', @module_or_batch = NULL, @params = NULL, @hints = N'OPTION(USE PLAN N''?'')' .8 테스트쿼리를 재실행하여, 기존 실행계획을 사용하는지 확인한다 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.NAME HAVING SUM(ORDERQTY) > 10 ORDER BY TOTAL DESC .9 확인되었으면, 계획지침을 삭제한다 EXEC SP_CONTROL_PLAN_GUIDE N'DROP', N'Guide_userplan' GO G Task 5: 파라미터화(paramemterization) .10 상수가 들어있는 쿼리 확인 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.NAME www.SQLAcademy.com
  • 46. 46 HAVING 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.NAME HAVING SUM(ORDERQTY) > 10 ORDER 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 www.SQLAcademy.com