728x90

저장 프로시저의 테스트 자동화


James McCaffrey _ Volt Information Sciences, Inc.의 직원
testrun@microsoft.com.


많은 Windows 기반 응용 프로그램에는 저장 프로시저가 포함된 SQL Server 백 엔드 구성 요소가 있습니다. 프런트 엔드 코드로 기능을 자동으로 테스트하는 기법은 잘 알려져 있지만 저장 프로시저의 테스트 자동화를 작성하는 기법은 별로 알려져 있지 않습니다. SQL Server 2005는 크게 향상된 Microsoft .NET Framework과의 통합 능력을 비롯하여 C# 및 기타 .NET 대상 언어로 저장 프로시저를 작성하는 기능을 제공합니다. 이로 인하여 확실히 저장 프로시저의 사용과 저장 프로시저에 대한 철저한 테스트의 중요성이 증가하였습니다.


이 문서에 사용된 코드 다운로드: TestRun0409.exe (124KB)


이 칼럼에서는 SQL Server 2005를 처음 사용할 때 미리 준비할 수 있도록 단순하지만 대표적인 SQL 저장 프로시저를 만드는 방법을 안내한 다음 그 기능을 검증하는 강력한 테스트 자동화를 빠르게 작성하는 방법을 알려줍니다. 또한 SQL 저장 프로시저에 대한 테스트 자동화를 작성하는 주요 원칙을 설명합니다.

데이터베이스에 액세스하는 모든 응용 프로그램 또는 서비스는 저장 프로시저를 사용할 수 있습니다. 이러한 경우 SQL 저장 프로시저를 응용 프로그램의 보조 기능으로 생각할 수 있습니다. 응용 프로그램의 개별 기능에 대한 테스트 자동화 작성을 보통API 테스트라고 하며 이러한 테스트를 작성하기 위한 단위 테스트 방법은 잘 알려져 있습니다. 그러나 앞에서 언급한 것처럼 SQL 저장 프로시저에 대한 테스트 자동화의 작성은 그다지 잘 알려져 있지 않습니다.


그림 1 직원 데이터베이스 액세스

학습 내용을 가장 잘 이해할 수 있도록 두 그림을 이용하여 설명하겠습니다. 직원 정보 데이터베이스에 액세스하는 응용 프로그램을 개발한다고 가정합시다. 그림 1은 단순하지만 대표적인 그러한 데이터베이스의 예제입니다. List Employees라는 단추를 누르면 포함된 SQL 문을 이용하여 백 엔드 SQL 데이터에 액세스하지만 Employee Status Code는 usp_empStatusCode라는 저장 프로시저를 이용하여 검색됩니다. 이것이 테스트할 저장 프로시저입니다. 그림 2는 그 테스트를 수행하는 테스트 실행을 보여줍니다.


그림 2 저장 프로시저 테스트 결과

이 예제에서 테스트 자동화는 프로그래밍 방식으로 직원 ID를 저장 프로시저에 공급하고 실제 상태 코드 반환 값을 포착하고 예상 값과 비교하여 테스트가 성공인지 실패인지를 결정합니다. 결과는 테스트 파일에 쓰여집니다. 여기에서는 6개의 테스트 사례만 사용합니다. 그러나 실제 환경에서는 물론 수천 개의 사례가 있을 것입니다.

이면에는 dbProseware라고 하는 SQL 데이터베이스에 tblEmployees라는 직원 정보 테이블이 있습니다. 다음 코드 조각에 표시된 바와 같이 예제 응용 프로그램은 먼저 데이터베이스에 연결한 다음 저장 프로시저 호출을 준비하여 usp_empStatusCode 저장 프로시저를 호출합니다.


string connString =
"server=(local);database=dbProseware;Integrated Security=SSPI";
SqlConnection conn = new SqlConnection(connString);
conn.Open();
SqlCommand cmd = new SqlCommand("usp_empStatusCode", conn);
cmd.CommandType = CommandType.StoredProcedure;


그런 다음 응용 프로그램은 저장 프로시저 반환 값과 단일 입력 매개 변수를 설정합니다.


SqlParameter p=cmd.Parameters.Add("ret_val", SqlDbType.Int, 1);
p.Direction = ParameterDirection.ReturnValue;

p=cmd.Parameters.Add("@empID", SqlDbType.Char, 3);
p.Direction = ParameterDirection.Input;
p.Value = textBox1.Text;


그리고 최종적으로 응용 프로그램은 저장 프로시저를 호출하여 반환 값을 얻고 다음과 같이 응용 프로그램에 반환 값을 표시합니다.


cmd.ExecuteNonQuery();
int code =
(int)cmd.Parameters["ret_val"].Value;
textBox2.Text = code.ToString();


응용 프로그램에서 저장 프로시저를 사용할 때 추가적인 프로그래밍 작업이 종종 필요하지만 저장 프로시저는 스크립트 주입 공격을 받을 가능성이 더 적고, 대개 더 우수한 성능을 제공하며, 더 정교한 다중 문 논리를 허용하고 더 효과적인 프로그램 구조를 작성할 수 있습니다.

응용 프로그램의 UI를 사용하여 이 저장 프로시저를 수동으로 테스트하는 작업은 매우 지루하고 시간이 오래 걸리며 오류가 발생하기 쉽습니다. 그리고 제품 코드가 변경될 때마다 처음부터 다시 테스트해야 합니다. 그러므로 그림 2에서와 같이 테스트 사례 데이터를 프로그래밍 방식으로 전송하고 반환 값을 검토하여 저장 프로시저를 테스트해 봅시다. 여기서는 전체 시스템을 테스트하는 것이 아니라 응용 프로그램의 저장 프로시저만을 테스트한다는 것을 알아두십시오.


테스트할 저장 프로시저


특별 생산 환경에서 엔터프라이즈 관리자 프로그램을 사용하여 지속적으로 백 엔드 데이터베이스를 만들 수 있습니다. 그러나 필요할 때마다 데이터베이스를 다시 만들 수 있도록 SQL 데이터베이스 작성 스크립트를 작성하는 것이 훨씬 좋습니다. 기존 데이터베이스의 엔터프라이즈 관리자에서 데이터베이스 작성 스크립트를 생성할 수 있지만 그 결과 코드는 대개 거추장스럽습니다. 그림 3의 스크립트는 dbProseware라는 데이터베이스를 만들고 tblEmployees라는 이름의 테이블과 usp_empStatusCode라고 하는 사용자 정의 저장 프로시저를 만듭니다.


그림 3 Database Creation Script

같은 이름의 데이터베이스가 존재하는지 않는지 확인한 다음 dbProseware라는 데이터베이스와 tblEmployees라는 테이블을 만듭니다. 그런 다음 몇몇 기본 기능 테스트를 수행할 수 있도록 일부 개발자 데이터(개발 과정에서 사용된 데이터)를 삽입합니다.

스크립트 마지막 부분에서는 테스트할 usp_empStatusCode 저장 프로시저를 만듭니다. 이 저장 프로시저는 직원 ID를 받아들여 ID가 유효하지 않을 경우 0을 반환하고, 퇴사 일자가 있을 경우(현재 직원이 아닌 경우) 1, 2000년 1월 1일 이전에 고용된 경우 2, 2000년 1월 1일 이후 고용된 경우 3을 반환합니다. 이 저장 프로시저는 좋은 코딩 기법의 본보기는 아니며 코드를 간단하게 줄였다는 것을 알려드립니다.

프로시저를 통한 프로그래밍 경력자일 경우 일반 프로그래밍 언어의 함수처럼 SQL 저장 프로시저를 생각하는 경향이 있습니다. 그러나 SQL 저장 프로시저는 대부분 테이블이나 다른 데이터베이스 개체에 대한 논리적 종속성이 있기 때문에 일반 함수와 크게 다릅니다. 이 예제에서 usp_empStatusCode 저장 프로시저에서 반환된 값은 tblEmployees 테이블의 데이터에 전적으로 종속적이라는 점을 알아두십시오. 그러므로 SQL 저장 프로시저의 테스트는 일반 함수 테스트와 다소 다릅니다.


테스트 자동화 구조


여러 방법으로 SQL 저장 프로시저에 대한 테스트 자동화를 구조화할 수 있습니다. 여기서 설명하는 특정 구조는 여러 대규모 프로젝트에서 성공적으로 사용되었으나 중요한 대체 방법이 있습니다. 이에 대해서는 앞으로 설명하도록 하겠습니다. 이 테스트 자동화 구조는 세 개의 SQL 스크립트, 즉 makeDbProseware.sql, prepTestAuto.sql, runTestAuto.sql을 중심으로 만들어집니다. 실제로 그림 2에 표시된 테스트 실행 결과를 생성한 BAT 파일은 입력으로서 이러한 스크립트가 지정된 세 개의 osql.exe 호출에 불과합니다. osql 유틸리티를 사용하여 Windows 명령 프롬프트에서 T-SQL 문, 시스템 프로시저, 스크립트 파일을 입력할 수 있습니다.

이전 단원에서는 makeDbProseware.sql을 살펴보았습니다. 이 스크립트는 테스트할 저장 프로시저 usp_empStatusCode와 관련 테이블 tblEmployees을 포함하는 dbProseware를 만듭니다.

prepTestAuto.sql 스크립트는 테스트 자동화에 필요한 주요 두 구성 요소를 dbProseware 데이터베이스에 추가합니다. 첫 번째 추가 구성 요소는 테스트할 풍부한 직원 데이터로 테이블 tblEmployees를 채워 알려진 초기 상태를 만드는 tap_ResetState라는 이름의 테스트 자동화 유틸리티 저장 프로시저입니다. 두 번째 추가 구성 요소는 테스트 사례 ID, 테스트 사례 입력, 테스트 사례 예상 결과로 구성된 tblTestCases라는 이름의 테스트 사례 데이터 테이블입니다. tblTestCases의 각 행은 정확히 하나의 테스트 사례에 해당합니다.

runTestAuto.sql 스크립트가 대부분의 작업을 수행합니다. 이 스크립트가 각 데이터 행에 대해 테스트할 저장 프로시저를 호출하고 커서를 사용하여 한 번에 한 행씩 테스트 사례 테이블 tblTestCases를 반복합니다. 반환 값이 캡처되고 예상 결과와 비교되어 합격 또는 불합격 결과를 결정합니다. 테스트 사례 결과가 나온 후 그 결과가 외부 결과 파일에 기록됩니다.


그림 4 테스트 시스템

그림 4의 도표는 테스트 자동화 시스템의 여러 요소가 작동하는 방식을 설명합니다.


테스트 자동화 준비


그림 5의 테스트 데이터베이스 준비 스크립트 prepTestAuto.sql은 데이터베이스 상태를 재설정하는 저장 프로시저를 추가하여 개발 데이터베이스를 증가시킵니다. 이것은 다음 두 가지 이유 때문에 필수적입니다. 첫째, 개발자 데이터가 저장 프로시저를 완벽하게 테스트하기에 충분히 많지 않기 때문입니다. 그래서 더 많은 데이터를 추가해야 합니다. 둘째, 저장 프로시저는 종종 데이터베이스를 변경합니다. 따라서 알려진 초기 상태로 데이터베이스를 재설정해야 합니다. 예를 들어 저장 프로시저는 테이블에 데이터를 추가하거나 테이블에서 행을 삭제할 수 있습니다. 이 예제의 usp_empStatusCode 저장 프로시저가 데이터베이스 상태를 변경하지 않는다고 해도 나중에 후회하는 것보다 안전한 것이 낫습니다.

그림 5에서 보는 바와 같이 준비 스크립트는 tblEmployees 테이블의 모든 데이터를 삭제한 다음 많은 테스트 직원으로 테이블을 채우는 tap_ResetState라는 저장 프로시저를 만듭니다. 그런 다음 준비 스크립트는 테스트 사례 데이터 테이블을 만들고 테이블을 채웁니다. 다양한 상태 데이터와 테스트 사례 데이터를 준비 스크립트에 하드코딩했습니다. 더 유연한 방법은 대량 복사 프로그램(BCP) 또는 데이터 변환 서비스(DTS) 프로그램을 사용하여 외부 파일에서 이러한 데이터 집합을 가져오는 것입니다. 또한 저장 프로시저에서 필요한 것보다 큰 테스트 입력을 허용하도록 empID 테스트 사례 필드를 char(3)가 아닌 varchar(10)으로 선언했습니다.


그림 5 Test Automation Preparation Script


테스트 자동화 실행

usp_empStatsCode 저장 프로시저의 자동 테스트를 실제로 수행하는 코드를 검토해 봅시다. 그림 6의 코드는 핵심 테스트 자동화입니다.


그림 6 Test Automation Preparation Script

테스트 데이터베이스가 있는지 확인한 후 다음과 같이 testCaseCursor라는 SQL 커서를 선언합니다.


declare testCaseCursor cursor fast_forward
for select caseID, empID, expectedResult
from tblTestCases
order by caseID


이 커서는 tblTestCases 테이블 데이터를 가리키고 한 번에 한 행씩 테이블 데이터를 반복할 수 있게 합니다. 보통 변수처럼 커서 변수 앞에 @ 문자가 오지 않는 것을 주의하여 보십시오. SQL Server 2000은 다양한 종류의 커서를 지원합니다. 여기에서 테스트 사례 데이터 간을 건너뛸 필요가 없고 고속 전달 커서가 일반적으로 성능이 가장 우수하기 때문에 고속 전달 커서를 사용합니다.

그런 다음 로컬 변수를 선언합니다. 즉 다음에서 보는 바와 같이 testCaseCursor 커서가 tblTestCase 데이터에서 추출한 테스트 사례 데이터를 보유하는 변수 세 개, usp_empStatusCode 저장 프로시저가 호출될 때 반환되는 실제 결과를 저장하는 변수 하나, 외부 텍스트 파일로 직접 테스트 결과를 쓰는 데 사용할 수 있는 변수 세 개를 선언합니다.


declare @caseID char(4), @empID varchar(10),
@expectedResult int,
@actualResult int
declare @fsoHandle int, @fileID int
declare @resultLine varchar(80)


테스트 결과를 보유하는 테이블을 만들 수 있지만 그 대신 결과를 테이블에 쓴 다음 결과 데이터를 외부 파일로 내보냅니다. SQL Server는 ActiveX 기술을 사용하여 외부 파일로 직접 결과를 쓰는 기능을 지원합니다. @fsoHandle 변수를 사용하여 파일 시스템 개체의 핸들을 저장합니다. 그런 다음 @fileID 변수가 파일 시스템 개체에서 획득한 결과 파일에 대한 정수 ID를 저장합니다. @resultLine 변수를 사용하여 테스트 사례 하나의 결과를 나타내는 텍스트 줄을 저장하고 외부 결과 파일에 그 텍스트 줄을 씁니다.

외부 결과 텍스트 파일을 준비하는 것으로 테스트 실행을 시작합니다.


exec sp_OACreate 'Scripting.FileSystemObject', @fsoHandle out
-- create object
exec sp_OAMethod @fsoHandle, 'OpenTextFile', @fileID out,
'C:\TestStoredProcs\results.txt', 8, 1


첫 번째 문은 FileSystemObject 개체의 인스턴스를 만들고 그에 대한 참조를 @fsoHandle 변수에 저장합니다. 다음 줄은 추가할 결과 파일을 엽니다. 여기에서는 단순하도록 결과 파일의 이름과 위치를 하드코딩하였으나 이 정보를 매개 변수화할 것입니다. 좀 이상하게 보이는 8과 1 매개 변수는 OpenTextFile을 실행하여 추가할 결과 파일을 열거나 파일이 없을 경우 파일을 만듭니다.

'WriteLine' 매개 변수와 함께 sp_OAMethod 저장 프로시저를 사용하여 결과 파일에 몇몇 예비 헤더 정보를 쓴 후에, 테스트 사례 데이터를 반복할 커서를 만들고 데이터베이스를 알려진 상태로 초기화합니다. Open 문은 변수 이 변수가 속하는 메모리 내부 결과 집합(여기에서 tblTestCases)를 가리키도록 testCaseCursor를 초기화합니다.


open testCaseCursor
exec tap_ResetState
fetch next
from testCaseCursor
into @caseID, @empID, @expectedResult


전부 정확하지는 않더라도 데이터 첫 행 전에 testCaseCursor가 tblTestCases의 맨 처음 데이터를 가리킨다고 가정하는 것이 유용합니다. Fetch next 문은 다음 데이터 행(여기에서는 첫 행)을 가져오고 위치를 기준으로 지정된 로컬 변수에 가져온 값을 저장합니다.

대량의 자동화가 while 루프를 통해 수행됩니다.


while @@fetch_status = 0
begin
-- create known state (call tap_ResetState)
-- execute stored procedure under test
-- determine pass or fail
-- write result
fetch next -- next test case
from testCaseCursor
into @caseID, @empID, @expectedResult
end


@@fetch_status는 현재 연결에서 모든 커서에서 마지막으로 시도된 반입 결과를 보유하는 전역 변수입니다. 값 0은 마지막 반입이 성공했음을 나타냅니다(값 -1 또는 -2는 실패를 나타냄). 그러므로 @@fetch_status를 사용하여 커서가 가리키는 전체 결과 집합을 반복했을 때를 확인할 수 있습니다. 루프 내에서의 처리는 실제로 다음과 같이 매우 단순합니다.


exec tap_ResetState
exec @actualResult = usp_empStatusCode @empID


도우미 저장 프로시저 tap_ResetState를 호출하여 알려진 상태를 만듭니다. 특히 테이블 tblEmployees의 모든 행을 삭제한 다음 많은 테스트 데이터로 테이블을 다시 채웁니다. 이제 테스트할 저장 프로시저를 실행하여 커서에 의해 반입된 테스트 사례 입력 데이터를 전달한 다음 실제 반환 값을 캡처할 수 있습니다. tap_ResetState 저장 프로시저의 호출 위치가 매우 중요합니다. 모든 테스트 전에, 반복적으로 호출되도록 While 루프 내에서 tap_ResetState을 호출합니다. 이 예제에서 테스트할 저장 프로시저 usp_empStatusCode는 dbProseware 데이터베이스의 상태를 변경하지 않으며 따라서 while 루프 외부에서 한 번만 호출함으로써 성능을 향상시킬 수 있었습니다. 그러나 경험상 대부분의 경우 저장 프로시저가 시스템 상태에 대해 어떠한 작업을 수행하는지에 관하여 아무런 가정을 하지 않고 주요 자동화 코드의 while 루프 내에서 상태를 항상 다시 만드는 것이 좋습니다. 각각의 모든 테스트 호출 전에 상태를 다시 만들 경우 발생하는 방문 횟수(performance hit)는 테스트 유효성 검사의 상당한 향상의 대가로 지불해야 하는 대체적으로 작은 비용입니다.

테스트 사례의 합격 또는 실패를 결정하기 위해 테스트하는 저장 프로시저를 호출하여 얻은 실제 값과 테스트 사례 테이블에서 반입된 예상 값과 비교합니다. 사실 다음 코드는 간단하게 작성할 수 있었습니다.


if (@actualResult = @expectedResult)
set @resultLine = @caseID + ' Pass '
else
set @resultLine = @caseID + ' FAIL '


그런 다음 다음과 같이 결과를 결과 파일에 썼습니다.


exec sp_OAMethod @fileID, 'WriteLine', null, @resultLine


물론 여러분도 이 예제에서와 같이 결과 파일에 더 자세한 설명 정보를 표시하기를 원할 것입니다. runTestAuto.sql 스크립트는 실행할 때마다 메모리가 누수되지 않도록 할당한 자원을 정리한 후 종료됩니다.


자동화 기능의 자동화


데이터베이스 작성 스크립트, 자동화 준비 스크립트, 자동 실행 스크립트가 작성되었으므로 이제 쿼리 분석기 프로그램에서 차례로 이 스크립트를 실행할 수 있습니다. 아니면, 세 스크립트를 실행하는 osql.exe 명령을 실행하는 간단한 BAT 파일을 작성하는 방법도 있습니다.


@echo off
rem runTests.bat

osql -S(local) -E -i makeDbProseware.sql -n > nul
osql -S(local) -E -i prepTestAuto.sql -n > nul
osql -S(local) -E -i runTestAuto.sql -n > nul

echo.
echo Test run complete
echo.


-E 스위치를 지정하면 osql에서 현재 Windows 로그인을 사용하여 Windows 인증 연결을 요청합니다. 이 스위치는 SQL Server 인스턴스에 연결하는 가장 안전한 옵션입니다. -n 스위치를 지정하면 줄 번호가 출력되지 않습니다. 또한 이 예제에서는 > nul을 지정하여 출력을 재지정함으로써 기타 메시지를 표시하지 않고 출력 표시를 더 깔끔하게 만들었습니다. 물론 생산 환경에서는 얻을 수 있는 모든 정보를 표시해야 할 것입니다. 앞에서 설명한 것과 같은 BAT 파일을 만든 후에 엔터프라이즈 관리자를 사용하여 편하게 설정할 수 있는 SQL Server 에이전트의 작업 기능을 사용하거나 Windows Scheduler를 사용하여 자동으로 테스트 스크립트를 시작하도록 쉽게 예약할 수 있습니다.


결론


SQL 저장 프로시저에 대한 테스트 자동화를 작성할 때 직면하는 기술적 문제 외에 빌드 관리 문제를 해결해야 합니다. 소규모 생산 환경에서는 제품 코드 베이스의 변경이나 새 빌드의 코드 베이스가 삭제된 경우와 같은 변경을 인지할 수 있을 것입니다. 그러나 대규모 생산 환경에서는 이러한 변경을 관리하기가 매우 어려울 수 있습니다. 예전에 대규모 제품에 대한 테스트 자동화 작업을 할 때 빌드 트리의 잘못된 분기를 3일 동안 테스트하여 변경을 찾았던 기억이 아직도 생생합니다! 테스트 팀 관리는 이 칼럼의 범위를 벗어나지만 그것은 테스트 자동화 구조를 개발할 때 명심해야 할 중요한 사항입니다.

이 칼럼에서 설명한 테스트는 SQL 구성 요소가 포함된 응용 프로그램을 테스트하는 여러 방법 중 하나일 뿐이라는 사실을 기억하십시오. 철저한 테스트를 위해서는 시스템을 구성하는 모든 계층을 테스트해야 합니다. 사용자 인터페이스, 응용 프로그램-SQL 인터페이스, 시스템에 있을 수 있는 기타 모든 인터페이스(HTTP, 소켓, 명명된 파이프, 서비스 등)를 통해 응용 프로그램을 테스트해야 합니다. 또한 여기에서 설명한 기법은 SQL 저장 프로시저 기능만을 테스트합니다. 스트레스 테스트, 성능 테스트, 기타 테스트도 고려해야 합니다. 이 칼럼에서 제시된 기본 구조를 사용하여 이러한 여러 분야의 테스트를 수행해야 할 것입니다.

728x90

1. mssql2000에서 백업된 파일을 가지고 mssql2005서버로 온다

 예) testdb를 백업해서 백업 파일이 testdb.bak라고 하고 c:넣었다고 가정한다.


2. restore filelistonly from disk='C:test.bak'를 해서 기존 디비 설정 정보를 확인 한다.

기존 정보가 : Date :D:Microsoft SQL ServerMSSQLDatatestdb_Data.MDF

                   Log : D:Microsoft SQL ServerMSSQLDatatestdb_Log.LDF


3. restore database testdb from disk='C:testdb.bak'

with move 'testdb_Data' to 'C:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLDatatestdb.mdf', move 'testdb_Log' to 'C:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLDatatestdb_log.LDF'

로 실행... (여기서 경로 및 MDF, LDF는 2005에 설정되어 있는 정보에 맞게 설정해야 된다.

파일 1에서 데이터베이스 'testdb', 파일 'testdb_Data'에 대해 33528개의 페이지를 처리했습니다 .
파일 1에서 데이터베이스 'testdb', 파일 'testdb_Log'에 대해 4개의 페이지를 처리했습니다 .
데이터베이스 'testdb'을(를) 버전 539에서 현재 버전 611(으)로 변환하는 중입니다.
데이터베이스 'testdb'을(를) 버전 539에서 버전 551(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 551에서 버전 552(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 552에서 버전 553(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 553에서 버전 554(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 554에서 버전 589(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 589에서 버전 590(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 590에서 버전 593(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 593에서 버전 597(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 597에서 버전 604(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 604에서 버전 605(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 605에서 버전 606(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 606에서 버전 607(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 607에서 버전 608(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 608에서 버전 609(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 609에서 버전 610(으)로 업그레이드하는 중입니다.
데이터베이스 'testdb'을(를) 버전 610에서 버전 611(으)로 업그레이드하는 중입니다.
RESTORE DATABASE이(가) 33532개의 페이지를 836.441초 동안 처리했습니다(0.328MB/초).

이렇게 메시지가 나올것이다.


데이터베이스가 이전 버전의 SQL Server 에서 SQL Server 2005 로 업그레이드되면 데이터베이스는 기존 호환성 수준을 유지합니다.

4. sp_dbcmptlevel 'a'


현재 호환성 수준은 80입니다.


5. sp_dbcmptlevel 'a','90' -- 호환성 수준을 MSSQL2005로 바꿉니다.

 

6.  그리고 계정을 생성한다 testid라고 만들었다고 가정한다.


7. USE db명
EXEC sp_change_users_login 'Update_One', '사용자', '로그인'

예) USE testdb
EXEC sp_change_users_login 'Update_One', 'testid', 'testid'

-- 중간의 s2kuser 정보는 DB의 사용자이고, 뒤의 s2kuser는 새로 SQL 2005에서 만들어준 로그인 이름입니다.


8. test라는 디비에 olduser라는 계정으로 사용하고 있었는데

2005로 옮겨 지면서 test라는 디비에 newuser라는 계정으로 사용을 하고 싶다면
USE test; --복원한 DB명
GO
EXEC sp_change_users_login 'Update_One', 'olduser', 'newuser';
728x90

DBCC DBREINDEX 란 무엇인가?


DBCC DBREINDEX

지정한 데이터베이스의 테이블에 대해 하나 이상의 인덱스를 다시 작성합니다.

DBCC DBREINDEX는 테이블의 특정 인덱스나 테이블에 정의된 모든 인덱스를 다시 작성합니다. DBCC DBREINDEX는 인덱스를 동적으로 다시 작성함으로써 PRIMARY KEY나 UNIQUE 제약 조건을 보장하는 인덱스를 다시 작성할 때 해당 제약 조건을 삭제했다가 다시 만들 필요가 없습니다.

DBCC DBREINDEX를 사용하면 하나의 명령문에서 테이블의 모든 인덱스를 다시 작성할 수 있습니다. 각 DROP INDEX와 CREATE INDEX 문이 원자성을 가지려면 트랜잭션을 사용해야 하는 반면, DBCC DBREINDEX는 하나의 명령문에서 작업이 수행되므로 자동으로 원자성을 갖습니다. 또한 DBCC DBREINDEX를 사용하면 각 DROP INDEX와 CREATE INDEX 문을 사용할 때보다 최적화를 더 많이 활용할 수 있습니다.

DBCC DBREINDEX는 시스템 테이블에 대해 사용할 수 없습니다.

구문

DBCC DBREINDEX
    (     [ 'database.owner.table_name'    
           
[ , index_name
                 [ , fillfactor ]
            ]
        ]
    )     [ WITH NO_INFOMSGS ]

인수

'database.owner.table_name'

지정한 인덱스를 다시 작성할 테이블의 이름입니다. 데이터베이스, 소유자, 테이블 이름은 식별자에 대한 규칙을 따라야 합니다. 자세한 내용은 식별자 사용을 참조하십시오. databaseowner 부분이 제공된 경우 전체 database.owner.table_name을 작은따옴표(')로 묶어야 합니다. table_name만 지정할 경우에는 작은따옴표를 사용할 필요가 없습니다.

index_name

다시 작성할 인덱스의 이름입니다. 인덱스 이름은 식별자에 대한 규칙을 따라야 합니다. index_name을 지정하지 않거나 ' '로 지정하면 테이블의 모든 인덱스가 다시 작성됩니다.

fillfactor

인덱스를 만들 때 각 인덱스 페이지에서 데이터 저장에 사용되는 공간의 비율입니다. 클러스터된 인덱스가 다시 작성되므로 fillfactor는 원래 채우기 비율을 다시 작성된 인덱스와 다른 클러스터되지 않은 인덱스의 새 기본값으로 대체합니다. fillfactor가 0이면 DBCC DBREINDEX는 인덱스가 만들어질 때 지정된 원래 fillfactor를 사용합니다.

WITH NO_INFOMSGS

심각도가 0에서 10 사이인 모든 정보 메시지를 표시하지 않습니다.





인덱스도 데이터입니다. 그래서 데이터가 추가되고 삭제되고 수정 됨에 따라서 인덱스 정보도 변경됩니다.
그러면 인덱스가 조각조각 찢어지는 현상이 발생하는데, 윈도우의 조각 모음과 비슷한 일을 하는게 DBREINDEX입니다.



다음은 pubs 데이터베이스의 authors 테이블에서 채우기 비율을 80으로 설정하여 au_nmind 클러스터되지 않은 인덱스를 다시 작성하는 예제입니다.

 

DBCC DBREINDEX ('pubs.dbo.authors', UPKCL_auidind, 80)

 


다음은 fillfactor 값을 70으로 사용하여 authors 테이블의 모든 인덱스를 다시 작성하는 예제입니다.


DBCC DBREINDEX (authors, '', 70)


한번에 한 서버의 모든 데이터베이스의 인덱스 재 작성하기

----------------------------------------------------------------------

/*
sp_name : usp_allReindex

sp_Explanation : 디비 서버의 모든 테이블에 대해 DBCC DBREINDEX를 실행합니다.

Input Parameters : None

Output Parameters : None

Usage : exec usp_allReindex
*/

ALTER PROCEDURE usp_allReindex
AS

-- 변수 선언
DECLARE @SQLString varchar(300), @dbname varchar(30), @tblname varchar(30)

SET NOCOUNT ON

-- 테이블 리스트 저장 테이블
CREATE TABLE #tables
(
    tblname varchar(30)
)

-- 한 서버의 디비 목록을 위한 커서 시작
DECLARE cur_dbList CURSOR
FOR
SELECT name FROM master..sysdatabases WHERE name NOT IN ('master','model','msdb','tempdb') ---- (1)

OPEN cur_dbList
FETCH cur_dbList INTO @dbname

WHILE @@fetch_status = 0
BEGIN
    TRUNCATE TABLE #tables
    SET @SQLString = 'insert into #tables select name from ' + @dbname + '..sysobjects where type = ''U'''
    EXEC (@SQLString)

    -- 각 디비의 테이블 목록을 위한 커서 시작
    DECLARE cur_tblList CURSOR
    FOR
    SELECT tblname FROM #tables

    OPEN cur_tblList
    FETCH cur_tblList INTO @tblname

    WHILE @@fetch_status = 0
    BEGIN
        SET @SQLString = 'DBCC DBREINDEX (''' + @dbname + '..' + @tblname + ''', '''', 90)' ---- (2)
        EXEC (@SQLString)
        FETCH cur_tblList INTO @tblname
    END

    CLOSE cur_tblList
    DEALLOCATE cur_tblList

    FETCH cur_dbList INTO @dbname
END

CLOSE cur_dbList
DEALLOCATE cur_dbList

DROP TABLE #tables

---------------------------------------------------------------------------------------



1) 에서 시스템 데이터베이스의 dbid 는 4번까지 고정적입니다.
사용자 데이터베이스는 dbid가 유동적입니다. 즉 삭제하고 다시 만들면 dbid를 재 사용합니다.
그래서 명확하게 시스템 데이터베이스의 이름을 지정해서 사용자 데이터베이스를 추출 하는게 좋을 것 같습니다.

(2) 에서 DBCC DBREINDEX의 사용법을 활용해서 원하는 방식으로 인자를 주시면 됩니다.

+ Recent posts