블로그 이미지
정홍주
Azure에 대한 내용뿐만 아니라 새로운 트렌드로 빅데이터, BI, SharePoint, 앱 등의 내용을 다룹니다.

calendar

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Notice

2012.05.04 21:42 SQL

뉴스그룹에 질문이 올라와 이리저리 직접 검색하다 보니 잘 정리되어 있는 글이 있어 블로깅을 합니다. 제품 버전별 최신 업데이트까지 반영되어 있습니다.

http://sqlserverbuilds.blogspot.com/

 2012년 4월까지 반영된 빌드입니다.

Microsoft SQL Server 2012 11.00.2316
Microsoft SQL Server 2008 R2 10.50.2811
Microsoft SQL Server 2008  10.00.5775
Microsoft SQL Server 2005  9.00.5296
Microsoft SQL Server 2000  8.00.2301

 

 

posted by 정홍주
2012.05.02 08:30 SQL

SQL Server 2012 T-SQL New Feature –THROW

 

이번 내용은 오류 처리에 대한 간단한 내용입니다. .NET 프로그래밍에서 에러 핸들링은 try catch 구문을 통해 작업을 하게 되며 class 등에서는 catch 문장에서 오류를 UI 단으로 아래와 같이 throw 시켜주게 됩니다.

try

            {

 

            }

            catch (System.DivideByZeroException ex)

            {

                throw new System.Exception(ex.Message);

            }

        }

 

SQL Server 2005 버전부터 TRY, CATCH 문장을 지원해주고 있었는데 에러를 발생시키는 내용은 오류 메시지를 사전에 등록해두거나 아니면 사용자 지정 메시지를 RAISERROR 구문을 사용했었습니다.

SQL Server 2012 버전부터는 THROW 구문을 사용해야 하며 앞에서 살펴본 몇몇 기능들과 마찬가지로  .NET 프로그래밍과 거의 유사합니다.

THROW [ { error_number | @local_variable },

        { message | @local_variable },

    { state | @local_variable }

] [ ; ]

 

 

간단한 예제를 한번 살펴보도록 하겠습니다.

Deparment 테이블의 경우 Name에 고유인덱스가 걸려있어 아래와 같이 기존 부서 이름을 입력시는 오류가 발생하게 됩니다. CATCH 문장에서 THROW를 통해 응용 프로그램이나 호출하는 프로시저로 오류를 전달할 수 있습니다.

BEGIN TRY

             INSERT [HumanResources].[Department] (Name, GroupName)

             VALUES ('Engineering','Manufacturing')

END TRY

BEGIN CATCH

              THROW;

 

END CATCH

 

--(0 행이 영향을 받음)

--메시지 2601, 수준 14, 상태 1, 3

--고유 인덱스 'AK_Department_Name'() 포함하는 개체 'HumanResources.Department' 중복 행을 삽입할 없습니다. 중복 값은 (Engineering)입니다.

 

 

물론 .NET 프로그래밍처럼 사용자 지정 오류메시지를 아래와 같이 THROW 시킬 수 있습니다.

BEGIN TRY

             INSERT [HumanResources].[Department] (Name, GroupName)

             VALUES ('Engineering','Manufacturing')

END TRY

BEGIN CATCH

              THROW 50001,'부서 이름 중복',1;

 

END CATCH

 

--(0 행이 영향을 받음)

--메시지 50001, 수준 16, 상태 1, 7

--부서 이름 중복

 

THROW 구문 전에 오류로그 저장등을 위해 ERROR_NUMBER() 등을 사용할 수 있습니다.

 

BEGIN TRY

             INSERT [HumanResources].[Department] (Name, GroupName)

             VALUES ('Engineering','Manufacturing')

END TRY

BEGIN CATCH

              SELECT  ERROR_NUMBER(),  ERROR_PROCEDURE(), ERROR_MESSAGE();

              THROW 50001,'부서 이름 중복',1;

              

END CATCH

 

THROW에 대한 자세한 내용은 아래 링크를 참조할 수 있습니다.

http://msdn.microsoft.com/ko-kr/library/ee677615.aspx

 

posted by 정홍주
2012.04.25 09:58 SQL

SQL Server 2012 Update TTT에 왔습니다. 

주로 다루는 내용은 Administrator, Developer 와 BI에 대한 3일 교육인데
여기 날씨가 비가오고 그러네요.

관련 링크와 예제 등이 RTM으로 업데이트 되었으므로 추후 링크하도록 하겠습니다.

posted by 정홍주
2012.04.18 08:30 SQL

SQL Server 2012 T-SQL New Feature –LEAD, LAG

 

이번에는 LEAD, LAG 함수를 알아보려고 합니다.

http://technet.microsoft.com/ko-kr/library/hh213125(v=sql.110).aspx

 

LEAD ( scalar_expression [ ,offset ] , [ default ] )

    OVER ( [ partition_by_clause ] )

LEAD는 자체 조인을 사용하지 않고 동일한 결과 집합에 있는 다음 행의 데이터에 액세스합니다.

LAG (scalar_expression [,offset] [,default])

    OVER ( [ partition_by_clause ] order_by_clause )

LAG는 자체 조인을 사용하지 않고 동일한 결과 집합에 있는 이전 행의 데이터에 액세스합니다.

 

가끔 가다 이상한 요구사항(전전년도, 전년도, 현재년도의 매출과 판매율)이 나오는데 쿼리로 작성하기에는 상당히 까다로울 수 있는 내용입니다.

 

위와 같은 쿼리문의 결과에서 원하는 결과는 어떤 내용이냐 하면 해당 값의 이전 값과 다음 값을 다음과 같이 표시해달라는 겁니다.

7 4일의 이전 판매 합은 7 3일로 15012가 되며 다음 판매 합은 7 5일로 15012 가 됩니다. 일별 판매 차이를 알 수 있습니다.

이전 쿼리에서는 Self 조인을 통해 이렇게 저렇게 ㅜ

 

 

 SQL Server 2012에서는 LEAD, LAG를 통해서 위와 같은 결과를 손쉽게 처리할 수 있습니다.

먼저 결과 행의 이전 행에 대한 내용을 처리하는 부분은 아래와 같이 처리됩니다.

SELECT

      oh.[OrderDate]

 

             ,LAG(SUM(od.[UnitPrice]),1) OVER (ORDER BY oh.[OrderDate] )  PrevValue

 

    , SUM(od.[UnitPrice]) AS SalesTotal             

  FROM [Sales].[SalesOrderHeader] oh INNER JOIN [Sales].[SalesOrderDetail] od

                           ON oh.[SalesOrderID] =od.[SalesOrderID]

GROUP BY oh.[OrderDate]

ORDER BY   oh.[OrderDate]

 

주문일로 정렬된 내용에 대해 이전 행의 판매량을 처리합니다.

LAG(SUM(od.[UnitPrice]),1) OVER (ORDER BY oh.[OrderDate] )  PrevValue

 

위 구문의 숫자 1은 바로 이전 행을 가리킵니다. 숫자 2를 사용한다면 전 전 행이 됩니다.

해당 값이 없을 경우 NULL을 반환하게 되는데 0 으로 표시하려면 아래와 같이 처리하면 됩니다;

LAG(SUM(od.[UnitPrice]),1,0) OVER (ORDER BY oh.[OrderDate] )  PrevValue

 

아래 쿼리의 결과를 보시면 될 것 같습니다.

SELECT

      oh.[OrderDate]

             ,LAG(SUM(od.[UnitPrice]),2,0) OVER (ORDER BY oh.[OrderDate] )  Prev2Value

             ,LAG(SUM(od.[UnitPrice]),1,0) OVER (ORDER BY oh.[OrderDate] )  PrevValue

 

    , SUM(od.[UnitPrice]) AS SalesTotal             

  FROM [Sales].[SalesOrderHeader] oh INNER JOIN [Sales].[SalesOrderDetail] od

                           ON oh.[SalesOrderID] =od.[SalesOrderID]

GROUP BY oh.[OrderDate]

ORDER BY   oh.[OrderDate]

 

 

LEAD는 결과 행의 다음 값을 나타냅니다. 아래 쿼리처럼 사용하면 되고 결과까지 캡쳐하지 않아도 될 것 같습니다.

SELECT

      oh.[OrderDate]

             ,LAG(SUM(od.[UnitPrice]),1,0) OVER (ORDER BY oh.[OrderDate] )  PrevValue

    , SUM(od.[UnitPrice]) AS SalesTotal             

 

             ,LEAD(SUM(od.[UnitPrice]),1) OVER (ORDER BY oh.[OrderDate] ) NextValue

 

  FROM [Sales].[SalesOrderHeader] oh INNER JOIN [Sales].[SalesOrderDetail] od

                           ON oh.[SalesOrderID] =od.[SalesOrderID]

GROUP BY oh.[OrderDate]

ORDER BY   oh.[OrderDate]

 

 LEAD LAG의 함수에 나오는 OVER 구문에서도 순위 함수와 동일하게 PARTITION BY를 사용할 수 있습니다. 아래의 경우는 TerritoryID 로 구분하여 LEAD LAG로 나타내야 합니다.

 

 TerritoryID 로 구분한 이전일의 판매량과 다음일의 판매량은 PARTITION BY를 사용하여 아래와 같이 가능합니다.

 

SELECT

      oh.[OrderDate] ,[TerritoryID]

             ,LAG(SUM(od.[UnitPrice]),1,0) OVER (PARTITION BY [TerritoryID] ORDER BY oh.[OrderDate] )  PrevValue

    , SUM(od.[UnitPrice]) AS SalesTotal             

 

             ,LEAD(SUM(od.[UnitPrice]),1) OVER (PARTITION BY [TerritoryID]  ORDER BY oh.[OrderDate] ) NextValue

 

  FROM [Sales].[SalesOrderHeader] oh INNER JOIN [Sales].[SalesOrderDetail] od

                           ON oh.[SalesOrderID] =od.[SalesOrderID]

GROUP BY oh.[OrderDate],[TerritoryID]

ORDER BY   oh.[OrderDate],[TerritoryID]

 

아래 결과 집합 그림은 TerritoryID 4 75일 데이터에 대한 내용과 위 구문의 결과입니다.

 

 결과 행의 이전, 다음 행의 값을 해당 행에 같이 표시해주려는 경우 LEAD, LAG를 이용하시면 아주 편한 결과를 제공할 수 있을 것 같습니다~

 

posted by 정홍주
2012.04.11 08:30 SQL

SQL Server 2012 T-SQL : 변환함수

 

이번에도 .NET 프로그래밍에서와 유사한 변환 함수를 한번 알아보도록 하겠습니다.

먼저 참조 링크는 아래와 같습니다.

http://msdn.microsoft.com/ko-kr/library/hh230993(v=sql.110).aspx

 

.NET 프로그래밍에서의 변환 CONVERT 함수는 아래와 같습니다. Parse, TryParse, Convert 등의 클래스나 메서드가 있습니다. 예를 들면 아래와 같습니다.

string s = "9000";

int price = Int32.Parse(s);

int price2 = 0;

if (Int32.TryParse(s, price2))

{

price = price2;

}

물론 다른 DateTime 데이터 형식도 가능하며 CultureInfo를 통한 내용도 지원합니다.

 

자 그럼 SQL Server 2012에서는 변환 함수가 어떤 내용이 지원될까요? 아래와 같은 함수를 제공하니 변환시 적용하면 아주 좋을 듯 합니다.

l  PARSE

PARSE 함수부터 알아보도록 하겠습니다.

PARSE ( string_value AS data_type [ USING culture ] )

요청한 데이터 형식으로 변환된 식 결과를 반환합니다 아래 내용을 보시면 바로 이해가 되실 듯 합니다. 입력값을 적절한 데이터 형식으로 변환하면서 Culture를 적용할 수 있습니다.

 

SELECT PARSE(N'2012 4 11 09:00, 수요일' AS datetime USING 'ko-KR');

--2012-04-11 09:00:00.000

SELECT PARSE(N'2012 4 11 오전 9' AS datetime USING 'ko-KR');

--2012-04-11 09:00:00.000

SELECT PARSE(N'2012 4 11, 오전 9' AS datetime USING 'ko-KR');

--2012-04-11 09:00:00.000

 

SELECT PARSE('\100000' AS money USING 'ko-KR') AS Result

--100000.00

SELECT PARSE('$100000' AS money USING 'en-US') AS Result

--100000.00

 

l  TRY_PARSE

.NET 프로그래밍도 마찬가지인데 잘못된 데이터에 대한 변환시 오류가 발생합니다. 아래처럼요.

SELECT PARSE('ddd' AS money USING 'en-US') AS Result

메시지 9819, 수준 16, 상태 1, 1

culture 'en-US'() 사용하여 문자열 'ddd'() money 데이터 형식으로 변환하는 오류가 발생했습니다.

 

 

데이터가 잘 들어오면 되지만 아니면 오류가 발생하므로 변환이 되는지 검사를 해볼 수 있는 함수가 TRY_PARSE 입니다. 변환이 가능하면 변환값이 나오고 아니면 NULL을 반환합니다.

.NET 프로그래밍과 사실 거의 유사합니다.  아래 구문을 보시죠.

 

SELECT TRY_PARSE('ddd' AS money USING 'en-US') AS Result

--NULL

 

 

 

l  TRY_CONVERT

TRY_CONVERT ( data_type [ ( length ) ], expression [, style ] )

TRY_PARSE와 유사합니다, 변환이 성공하면 값을 반환하며 실패하면 NULL을 반환합니다. Culture는 없으며 Style을 제공하는 것이 차이점입니다.

SELECT TRY_CONVERT(datetime2, '04/11/2012') AS Result;

--2012-04-11 00:00:00.0000000

SELECT TRY_CONVERT(datetime2, '13/11/2012') AS Result;

--NULL

 

DECLARE @dt DATETIME = PARSE(N'2012 4 11 오전 9' AS datetime USING 'ko-KR')

SELECT TRY_CONVERT(varchar(30), @dt,112) AS Result;

--20120411

 

이상으로 새롭게 제공되는 변환함수에 대한 내용을 정리했습니다.

 

posted by 정홍주
2012.04.04 08:30 SQL

 

SQL Server 2012에서의 FORMAT 함수

 

.NET에서는 날짜 형식이나 숫자 형식에 대한 FORMAT을 초기부터 제공해왔습니다. 그래서 아래와 같은 코드를 작성할 수 있습니다. CultureInfo를 통해 언어별 지원을 제공할 수 도 있습니다.

 

CultureInfo culture = new CultureInfo("fr-FR");

string dt = string.Format(culture, "{0:D}", DateTime.Now);

 

int i = 62500;

string price = i.ToString("C", culture);

string price2 = string.Format(culture, "{0:C}", i);

 

dt : "mardi 3 avril 2012"

price : "62 500,00 €"

price2 : "62 500,00 €"

 

 

SQL Server 에서는 날짜 형식이나 숫자 형식에 대한 지원을 .NET 응용 프로그램에서 처리하거나 별도의 테이블을 생성하여 처리했습니다. 또는 언어별 컬럼을 생성하여 처리해야 했습니다.

 

SQL Server 2012에서는 FORMAT 함수가 지원이 되어 .NET 과 거의 동일하게 작업이 가능합니다.

http://technet.microsoft.com/ko-kr/library/hh213505.aspx

 

l  날짜 형식에 대한 부분을 알아보도록 하겠습니다.

DECLARE @d DATE = GETDATE()

 

SELECT        FORMAT(@d, N'dd/MM/yyyy')

--03-04-2012

 

SELECT     FORMAT(@d, N'dddd, MMMM dd, yyyy', 'fr-fr')

--mardi, avril 03, 2012

 

SELECT     FORMAT(@d, N'dddd, MMMM dd, yyyy', 'en-US')

--Tuesday, April 03, 2012

 

 

l  숫자 형식에 대한 부분을 알아보도록 하겠습니다.

 

DECLARE @i INT=62500

SELECT price = FORMAT(@i, 'C')

--₩62,500

 

SELECT price = FORMAT(@i, 'C','en-US')

--$62,500.00

 

SELECT price = FORMAT(@i, 'N')

--62,500.00

 

SELECT price = FORMAT(0.625, 'P')

--62.50 %

 

 

위 내용을 보면 .NET 코딩과 유사하다는 것을 알 수 있습니다. 응용 프로그램에서 추가적인 처리를 하지 않고도 날짜, 숫자 형식의 문자열 포맷팅을 T-SQL에서도 FORMAT 함수를 통해 지원할 수 있습니다.

 

 

posted by 정홍주
2012.03.28 08:30 SQL

SQL Server 2012 T-SQL: CHOOSE, IIF 논리함수

 

새롭게 제공되는 내용 중에서 CHOOSE, IIF를 한번 사용해보도록 하겠습니다.

SELECT 구문에서 조건에 따라 값을 나타내려고 할 경우 CASE WHEN 문을 사용해서 처리했습니다. CASE 구문을 작성하면 코드가 길어지고 가독성이 좀 떨어지는 측면이 있었습니다.

 
l  CHOOSE

SQL Server 2012에서는 보다 더 간결하고 쉽게 처리 가능한 CHOOSE, IIF 구문이 제공됩니다.

아래 구문을 한번 살펴보시죠~

 

SELECT  CASE DATEPART(WEEKDAY, GETDATE())

                                WHEN 1 THEN N'일요일'

                                WHEN 2 THEN N'월요일'

                                WHEN 3 THEN N'화요일'

                                WHEN 4 THEN N'수요일'

                                WHEN 5 THEN N'목요일'

                                WHEN 6 THEN N'금요일'

                                WHEN 7 THEN N'토요일'

                     END

 

위 구문의 경우는 CASE WHEN 구문으로 작성한 내용인데 CHOOSE 구문으로 변경해보도록 하겠습니다. 더 간결해보입니다.

SELECT CHOOSE(DATEPART(WEEKDAY, GETDATE())                     , N'일요일',N'월요일',N'화요일',N'수요일',N'목요일',N'금요일',N'토요일')

 

CHOOSE 논리함수의 구문의 규칙은 아래와 같습니다.

CHOOSE ( index, val_1, val_2 [, val_n ] )

 

Index 1부터 시작하는 정수이며 val_1.., 등은 인덱스에 매치되는 임의의 데이터 형식입니다.

그러므로 1부터 반환하는 정수가 나오는 인수를 맨 처음에, 나머지는 해당 값을 정의하면 됩니다.

SELECT CHOOSE ( 3, 'Manager', 'Director', 'Developer', 'Tester' ) AS Result;

--Developer

3이므로 세 번째에 해당하는 Developer를 반환합니다.

 

CHOOSE 논리 함수에 대한 내용은 아래 링크를 참조하십시오.

http://technet.microsoft.com/ko-kr/library/hh213019(v=sql.110).aspx 

 

l IIF

또 다른 논리함수인 IIF 를 한번 살펴보겠습니다. 사실 IIF CASE 문의 약식 방법입니다. TRUE, FALSE에 따라 처리할 경우 IIF를 사용할 수 있습니다. IIF SQL Server Reporting의 식에서도 사용이 되었기 때문에 사용해보았다면 적용하시는데 큰 문제 없을 것으로 보입니다.

IIF ( boolean_expression, true_value, false_value ) 

boolean_expression TRUE 이면 true_value 가 반환됩니다. 

 

SELECT

[ProductID], [Name], [ListPrice]

, CASE WHEN [ListPrice] < 500 THEN  N'500이하'

           ELSE 

             CASE WHEN [ListPrice] < 1000 THEN N'1000이하' ELSE N'1000이상'
            
 END

           END AS ProceLevel

FROM [Production].[Product]

WHERE [ListPrice] >0

 

500보다 작으면 ‘500이하’, 500보다 크고 1000보다 작으면 ‘1000’이하, 1000보다 크면 ‘1000’이상입니다. IIF로 변환해보겠습니다 

SELECT

[ProductID], [Name], [ListPrice]

, IIF([ListPrice] < 500, N'500이하', IIF([ListPrice] < 1000, N'1000이하',N'1000이상')) AS ProceLevel

FROM [Production].[Product]

WHERE [ListPrice] >0  

/*

522      HL Touring Seat Assembly      196.92  500이하

680      HL Road Frame - Black, 58      1431.50 1000이상

706      HL Road Frame - Red, 58        1431.50 1000이상

707      Sport-100 Helmet, Red 34.99    500이하

708      Sport-100 Helmet, Black          34.99    500이하

*/

 

위 두 구문의 실행계획을 보면 똑같습니다. 편하고 가독성 있는 구문을 쓰면 될 것 같네요~


CASE 문 보다 더 간결한 CHOOSE, IIF 논리함수에 대한 내용을 살펴보았습니다.


posted by 정홍주
2012.03.21 08:30 SQL

SQL Server 2012의 강화된 T-SQL: 시퀀스(Sequence)

SQL Server 2012의 시퀀스에 대한 내용을 알아보도록 하겠습니다. 이전버전에서는 IDENTITY 라는 속성을 통해 순차적인 일련번호를 생성했습니다. 새롭게 시퀀스라는 개체가 제공되어 일련번호를 효과적으로 사용할 수 있을 것 같은데 아래에서 한번 살펴보도록 하겠습니다.

 

먼저 아래와 같이 데이터베이스에 테이블을 생성합니다.

 

CREATE TABLE Products

(

    ProductID INT NOT NULL PRIMARY KEY

    ,Name VARCHAR(200) NULL

,ModifiedDate DATETIME DEFAULT GETDATE()

);

 

Products 테이블에 ProductID를 일련번호로 생성하기 위해서는 IDENTITY를 사용했지만 별도의 시퀀스(Sequence) 개체를 아래와 같이 생성할 수 있습니다.

CREATE SEQUENCE PIdSequence AS INT

    START WITH 1

    INCREMENT BY 1;

 

초기값 1 , 증가값 1로 시퀀스(Sequence) 개체를 생성했습니다. 생성된 개체는 개체탐색기의 프로그래밍 기능, 시퀀스에서 살펴볼 수 있습니다.


시퀀스(Sequence)의 개체를 더블 클릭하면 아래와 같은 대화 상자를 볼 수 있는데 현재 값이나 다시 시작 순서, CACHE 에 대한 내용을 알 수 있습니다.

 

 위에서 생성한 Products 테이블에 시퀀스(Sequence) 개체를 적용해보도록 하겠습니다.

INSERT 구문 등에서 NEXT VALUE FOR PIdSequence 를 사용하면 됩니다.

 

INSERT INTO Products (ProductID, Name)

   VALUES (NEXT VALUE FOR PIdSequence, 'Coffece');

 

위 구문을 여러 번 실행하여 Products를 여러 개를 입력한 결과는 아래와 같습니다.

 

/*

1           Coffece             2012-03-19 09:54:00.327

2           Coffece             2012-03-19 09:54:00.913

3           Coffece             2012-03-19 09:54:01.400

4           Coffece             2012-03-19 09:54:01.853

5           Coffece             2012-03-19 09:54:02.277

*/

 

l  위에서 생성한 시퀀스(Sequence) 개체는 Products 테이블에만 종속된 것은 아니며 다른 테이블에서도 사용이 가능합니다. 다른 테이블에서 사용하면 해당 값은 증가되며 증가된 값을 계속 사용하게 됩니다.

NEXT VALUE FOR PIdSequence 을 실행할 경우 시퀀스(Sequence) 값은 증가하게 됩니다.

l  중간에 값이 비어 있는 경우 SET IDENTITY_INSERT 옵션을 쓰지 않고 누락된 값을 INSERT 하면 됩니다.

l  현재 값을 알려면 아래 구문을 실행할 수 있습니다.

SELECT cache_size, current_value

FROM sys.sequences

WHERE name = 'PIdSequence' ;

 

l  복제, SSIS 등의 경우 시퀀스(Sequence)를 사용할 경우 더 효과적으로 사용이 가능합니다.

l  CACHE 옵션이 있어 대용량 데이터를 처리하는 일련번호일 경우 Sequence가 우수할 것으로 보입니다.

 

posted by 정홍주
2012.03.14 08:30 SQL

 

SQL Server 2012의 강화된 T-SQL : 페이징 - OffSet/Fetch

 

개발자들이 리스트나 게시판에 대해서 페이징 하는 것은 기본적인 작업입니다.

물론 여러 가지 방법이 있습니다. TOP 구문과 WHERE 절을 통해서 하거나 ROW_NUMBER를 통해서 처리하거나 별도 쿼리를 통해서 하거나 기존 소스를 한번 살펴보면 여러 방법을 쓰고 있다는 것을 알 수 있습니다. 

SQL Server 2012에서는 Offset/Fetch 구문을 통해 효과적으로 페이징 쿼리를 작성할 수 있습니다. 일단 쿼리 구문이 간단해서 작업하기가 용이한 것 같습니다.

물론 저희 환경의 기존 데이터에 기존 페이징 쿼리와 Offset/Fetch 쿼리에 대한 성능 비교를 해봐야 하겠지만 여기에서는 간단한 사용법을 알아보도록 하겠습니다. 

자 먼저 구문을 한번 실행해보도록 하겠습니다.

아래 구문은 AdventureWorks2012에 있는 Product 테이블을 SELECT 한 결과입니다.

--[AdventureWorks2012]

SELECT ProductID, Name, ProductNumber, Color, Size FROM [Production].[Product]

ORDER BY ProductID DESC  

 

 

간단한 페이징을 해보도록 하겠습니다. 위 결과의 1 페이지에 해당하는 결과만 보여주는 내용입니다. 직접 값을 지정했습니다.

SELECT ProductID, Name, ProductNumber, Color, Size FROM [Production].[Product]

ORDER BY ProductID DESC  

OFFSET 0 ROWS

    FETCH NEXT 10 ROWS ONLY;

 

2 페이지를 보고 싶다면 아래와 같이 구문이 변경됩니다.

SELECT ProductID, Name, ProductNumber, Color, Size FROM [Production].[Product]

ORDER BY ProductID DESC  

OFFSET 10 ROWS

    FETCH NEXT 10 ROWS ONLY; 

 

변수로 대체되는지를 확인하기 위해 저장 프로시저를 아래와 같이 생성했습니다.

CREATE PROC usp_GetProducts

@Page INT

AS

DECLARE @Fetch INT =10;

DECLARE @OffSet INT= (@Page-1)*@Fetch

 

SELECT ProductID, Name, ProductNumber, Color, Size FROM [Production].[Product]

ORDER BY ProductID DESC  

OFFSET @OffSet ROWS

    FETCH NEXT @Fetch ROWS ONLY;

GO

 

프로시저를 실행하면 아래와 같은 결과를 얻을 수 있습니다. 

서브 쿼리를 이용해서 할 수 도 있습니다. 아래 구문을 참고하세요~

SELECT ProductID, Name, ProductNumber, Color, Size FROM [Production].[Product]

ORDER BY ProductID DESC  

OFFSET 10 ROWS

    FETCH NEXT (SELECT PageSize FROM [dbo].[AppSettings])  ROWS ONLY;

GO

 

 기존에 쓰던 쿼리가 없어 실행계획을 비교하기는 뭐하네요~ 

온라인 설명서에서 Offset/Fetch에 대한 내용은 아래 링크를 참조하십시오.

http://msdn.microsoft.com/ko-kr/library/ms188385(v=sql.110).aspx#Offset

  

Offset Fetch에 대한 제한 사항

l  외부 쿼리와 상관 관계를 만들 수 없습니다.

l  OVER 절은 OFFSET FETCH를 지원하지 않습니다.

l  OFFSET FETCH INSERT, UPDATE, MERGE DELETE 문에서 직접 지정할 수 없지만 이러한 문에 정의된 하위 쿼리에서는 지정할 수 있습니다

l  UNION, EXCEPT 또는 INTERSECT 연산자를 사용하는 쿼리에서는 쿼리 결과의 순서를 지정하는 마지막 쿼리에서만 OFFSET FETCH를 지정할 수 있습니다.

l  같은 쿼리 식(같은 쿼리 범위)에서 TOP OFFSET FETCH와 결합할 수 없습니다.

 

안정된 최적화를 위해서는 아래 조건을 만족해야 합니다.

l  쿼리에 사용되는 기본 데이터가 변경되지 않아야 합니다., 쿼리와 연결된 행이 업데이트되지 않거나 페이지에 대한 모든 쿼리 요청이 스냅숏 또는 직렬화 가능 트랜잭션 격리를 사용하여 단일 트랜잭션에서 실행되어야 합니다.
(
위 온라인 설명서의 단일 트랜잭션에서 여러 쿼리 실행쿼리 예를 참고하십시오.)

l  ORDER BY 절이 고유한 열 또는 열의 조합을 포함해야 합니다.


'SQL' 카테고리의 다른 글

SQL Server 2012 T-SQL: CHOOSE, IIF 논리함수  (0) 2012.03.28
SQL Server 2012의 강화된 T-SQL: 시퀀스(Sequence)  (0) 2012.03.21
SQL Server 2012의 강화된 T-SQL : 페이징 - OffSet/Fetch  (0) 2012.03.14
SQL Server 2012 RTM  (0) 2012.03.07
Hadoop  (0) 2012.02.13
Big Data  (0) 2012.01.19
posted by 정홍주
2012.03.07 07:28 SQL

SQL Server 2012 RTM

 

SQL Server 2012 RTM 이 다운로드 가능해졌습니다.(2012-03-06)

아래 페이지를 참고하십시오~

http://www.microsoft.com/sqlserver/en/us/default.aspx

 



또한 SQL Server 2012 Feature Pack 도 다운로드 가능합니다.

그리고 아래 링크를 통해 SQL Server 2012 Virtual Launch Event 에 등록하시면 많은 정보를 얻으실수 있습니다.
http://www.sqlserverlaunch.com/ww/Home

'SQL' 카테고리의 다른 글

SQL Server 2012의 강화된 T-SQL: 시퀀스(Sequence)  (0) 2012.03.21
SQL Server 2012의 강화된 T-SQL : 페이징 - OffSet/Fetch  (0) 2012.03.14
SQL Server 2012 RTM  (0) 2012.03.07
Hadoop  (0) 2012.02.13
Big Data  (0) 2012.01.19
SQL Server 2012 RC  (0) 2011.11.19
posted by 정홍주
prev 1 2 3 next