다음을 통해 공유


연습: Visual Studio 자동화 모델을 사용하여 데이터베이스 프로젝트 수정

업데이트: 2007년 11월

Visual Studio의 확장성 지원을 사용하면 데이터베이스 프로젝트를 프로그래밍 방식으로 수정할 수 있습니다. Visual Studio Team System Database Edition의 데이터베이스 프로젝트는 Visual C# 및 Visual Basic 프로젝트와 일관된 방식으로 Visual Studio 자동화 모델(디자인 타임 확장성 또는 DTE라고도 함)을 지원합니다. 이 모델에 대한 자세한 내용은 Visual Studio 환경 확장을 참조하십시오. 이 연습에서는 자동화 모델을 사용하여 다음과 같은 두 가지 작업을 수행하는 Visual Studio 매크로를 만듭니다.

  • 데이터베이스 프로젝트에 있는 모든 트리거의 빌드 작업을 전환합니다. 트리거가 "빌드"로 설정되어 있으면 매크로를 통해 "빌드에 없음"으로 변경됩니다. 트리거가 "빌드에 없음"으로 설정되어 있으면 매크로를 통해 "빌드"로 변경됩니다.

  • 디렉터리에 있는 모든 스크립트 파일을 데이터베이스 프로젝트의 폴더에 추가합니다. 폴더가 없으면 새로 만들어집니다. 특정 확장명이 있는 스크립트 파일만 추가됩니다.

또한 Visual Basic 또는 Visual C#으로 작성된 Visual Studio 추가 기능에서도 이러한 작업을 수행할 수 있습니다. 이 연습에서는 편의상 매크로를 사용합니다.

아래 절차에서는 다음과 같은 작업을 수행합니다.

  • 개체 형식별로 구성된 데이터베이스 프로젝트를 만들고 AdventureWorks 데이터베이스 스키마를 가져옵니다.

  • 매크로 탐색기를 시작하고 모듈을 만들어 매크로 및 지원하는 코드를 포함합니다.

  • 열려 있는 솔루션에 있는 데이터베이스 프로젝트의 모든 트리거에 대해 빌드 작업을 전환하는 매크로를 만듭니다.

  • 데이터베이스 프로젝트에 스크립트를 추가하는 매크로 및 지원하는 코드를 만듭니다.

  • 명령 창에서 ToggleTriggers 매크로를 실행합니다.

  • 매크로 탐색기에서 AddScriptsInDirectory 매크로를 실행합니다.

사전 요구 사항

이 연습을 완료하려면 Database Edition이 설치되어 있어야 합니다. 이 연습에서는 Microsoft SQL Server 2005를 실행하는 데이터베이스 서버에 AdventureWorks 샘플 데이터베이스 복사본을 설치했다고 가정합니다. 개체 형식별로 구성된 다른 데이터베이스 프로젝트를 대신 사용할 수도 있습니다. 또한 액세스 권한이 있는 디렉터리에 확장명이 .sql인 파일이 하나 이상 있어야 합니다.

데이터베이스 프로젝트를 만들려면

  1. Visual Studio를 시작합니다(아직 시작하지 않은 경우).

  2. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.

    새 프로젝트 대화 상자가 나타납니다.

  3. 프로젝트 형식 목록에서 데이터베이스 프로젝트 노드를 확장하고 Microsoft SQL Server를 클릭합니다.

  4. 템플릿 목록에서 SQL Server 2005를 클릭합니다.

  5. 이름에 MyAdvWorks를 입력하고 위치 및 솔루션 이름에 대해 기본값을 적용합니다.

  6. 기본적으로 선택되어 있지 않으면 솔루션용 디렉터리 만들기 확인란을 선택하고 확인을 클릭합니다.

    빈 MyAdvWorks 데이터베이스 프로젝트가 포함된 솔루션이 생성됩니다.

    다음에는 소스 데이터베이스에 대한 연결 문자열을 지정하는 데이터베이스 스키마 가져오기 프로세스를 시작합니다.

기존 AdventureWorks 데이터베이스에서 데이터베이스 스키마를 가져오려면

  1. 보기 메뉴에서 스키마 뷰를 클릭합니다.

    스키마 뷰가 아직 표시되지 않은 경우 표시됩니다.

  2. 스키마 뷰에서 MyAdvWorks를 클릭합니다.

  3. 프로젝트 메뉴에서 데이터베이스 스키마 가져오기를 클릭합니다.

    참고:

    MyAdvWorks를 마우스 오른쪽 단추로 클릭하고 데이터베이스 스키마 가져오기를 클릭할 수도 있습니다.

    데이터베이스 가져오기 마법사가 나타납니다.

  4. 소스 데이터베이스연결 목록에서 기존 AdventureWorks 데이터베이스에 해당하는 연결을 클릭합니다. 아직 이 데이터베이스에 연결하지 않은 경우 먼저 연결을 만들어야 합니다. 자세한 내용은 방법: 데이터베이스 연결 만들기를 참조하십시오.

  5. 마침을 클릭합니다.

    스키마를 가져올 때 데이터베이스에 있는 개체에 해당하는 프로젝트 항목이 솔루션 탐색기의 데이터베이스 프로젝트 아래에 나타납니다. 스키마 뷰에는 데이터베이스 프로젝트에 정의된 개체가 표시됩니다.

매크로 탐색기를 시작하여 모듈을 만들려면

  1. 보기 메뉴에서 다른 창을 가리킨 다음 매크로 탐색기를 클릭합니다.

    매크로 탐색기가 나타납니다.

  2. 매크로 탐색기에서 MyMacros 노드를 마우스 오른쪽 단추로 클릭하고 새 모듈을 클릭합니다.

    모듈 추가 대화 상자가 나타납니다.

  3. 이름에 BuildActionExample을 입력합니다.

  4. 추가를 클릭합니다.

  5. 매크로 탐색기에서 MyMacros 노드를 마우스 오른쪽 단추로 클릭하고 새 모듈을 클릭합니다.

    모듈 추가 대화 상자가 나타납니다.

  6. 이름에 ImportScriptsExample을 입력합니다.

  7. 추가를 클릭합니다.

    다음으로는 지정된 데이터베이스에 있는 모든 DML(데이터 조작 언어)의 빌드 작업을 전환하는 매크로를 만듭니다.

ToggleTriggers 매크로 만들기

ToggleTriggers 매크로는 업데이트할 트리거가 포함된 데이터베이스 프로젝트의 이름인 선택적 매개 변수 하나를 사용합니다. 프로젝트 이름을 지정하지 않으면 매크로에서 이를 지정하라는 메시지를 표시합니다. 솔루션의 각 프로젝트 형식을 대신 식별하고 모든 데이터베이스 프로젝트를 업데이트하도록 매크로를 수정할 수 있습니다. 그러나 이러한 접근 방식은 이 연습에서 다루지 않습니다.

ToggleTriggers 매크로를 만들려면

  1. 매크로 탐색기에서 BuildActionExample 모듈을 마우스 오른쪽 단추로 클릭하고 편집을 클릭합니다.

    Microsoft Visual Studio Macros 창이 나타납니다. 이 창에는 BuildActionExample 모듈의 내용이 표시됩니다.

  2. 모듈의 내용을 다음 VBScript 코드로 대체합니다.

    Imports System
    Imports System.ComponentModel
    Imports EnvDTE
    Imports EnvDTE80
    Imports System.Diagnostics
    
    Public Module BuildActionExample
    
        ' Macro to toggle the BuildAction for all DML triggers
        ' in a database project.
        ' Before running this macro, you must:
        ' 1) Ensure that a solution file is open and saved to disk.
        ' 2) Pass in the name of a database project contained in the
        '    open solution in the dbProjName parameter. 
        Sub ToggleTriggers(Optional ByVal dbProjName As String = "")
            Dim project As Project
    
            ' if the database project name was not passed in, prompt the user for it.
            If (String.IsNullOrEmpty(dbProjName)) Then
                dbProjName = InputBox("Type the database project name.")
                If (String.IsNullOrEmpty(dbProjName)) Then
                    Return
                End If
            End If
    
            ' Loop through each project until we find the one we want
            For Each project In DTE.Solution
                Dim projectItem As EnvDTE.ProjectItem
                'Look for a project whose name matches the parameter
                If (dbProjName.Equals(project.Name)) Then
                    'Then loop through the project items, looking for
                    'the Schema Objects folder.
                    For Each projectItem In project.ProjectItems()
                        If (projectItem.Name = "Schema Objects") Then
                            ' loop through the subfolders and list the files, looking for the Tables sub-folder
                            Dim subItem As EnvDTE.ProjectItem
                            For Each subItem In projectItem.ProjectItems()
                                If (subItem.Name = "Tables") Then
                                    ' loop through looking for the Triggers subfolder
                                    Dim subsubItem As EnvDTE.ProjectItem
                                    For Each subsubItem In subItem.ProjectItems()
                                        If (subsubItem.Name = "Triggers") Then
                                            ' okay, we're in the right folder, now set the build actions
                                            Dim triggerItem As EnvDTE.ProjectItem
                                            For Each triggerItem In subsubItem.ProjectItems()
                                                'MsgBox(" trigger: " + triggerItem.Name)
                                                Dim buildAction As EnvDTE.Property
                                                buildAction = triggerItem.Properties.Item("DBProjectBuildAction")
    
                                                ' here we toggle the build action. If it was NotInBuild(0),
                                                ' we set it to Build(1). If it was Build(1), then we set it
                                                ' to NotInBuild(0).
                                                If (buildAction.Value = 0) Then
                                                    buildAction.Value = 1
                                                ElseIf (buildAction.Value = 1) Then
                                                    buildAction.Value = 0
                                                End If
                                            Next
                                        End If
                                    Next
                                End If
                            Next
                        End If
                    Next
                End If
            Next
        End Sub
    End Module
    

    매크로는 이름이 지정한 이름과 일치하는 데이터베이스 프로젝트를 찾을 때까지 솔루션의 내용을 반복합니다. 또한 해당 프로젝트를 확인한 후에는 프로젝트 항목을 반복하여 솔루션 항목 폴더를 검색합니다. 매크로는 솔루션 항목 폴더에서 테이블 폴더를 검색하고, 다시 이 폴더 내에서 트리거 폴더를 검색합니다. 그런 다음 트리거별로 DBProjectBuildAction 속성 값을 검색합니다. 값이 1(빌드)이면 0(빌드에 없음)으로 전환되고 값이 0이면 1로 전환됩니다. 속성 창의 속성 이름은 빌드 작업이지만 기본 속성 이름은 DBProjectBuildAction입니다.

  3. 매크로 창에서 파일 메뉴를 열고 MyMacros 저장을 클릭합니다.

    다음으로는 지정된 데이터베이스 프로젝트에 디렉터리의 스크립트 파일을 추가하는 매크로를 만듭니다.

AddScriptsInDirectory 매크로 만들기

AddScriptsInDirectory 매크로는 스크립트 파일을 추가할 데이터베이스 프로젝트의 이름, 스크립트를 추가할 데이터베이스 프로젝트의 폴더 이름 그리고 매크로에서 가져올 스크립트 파일이 포함된 경로의 세 가지 매개 변수를 사용합니다. 매크로를 실행할 때 이들 매개 변수를 지정하지 않으면 이를 지정하라는 메시지가 표시됩니다. 메시지가 나타날 때 프로젝트 폴더의 이름을 지정하지 않으면 파일이 스크립트 폴더에 추가됩니다.

이 매크로는 앞에서 살펴본 매크로보다 복잡합니다. 편의상 다음과 같은 두 개의 함수와 두 개의 서브루틴을 만들어 AddScriptsInDirectory 매크로를 빌드합니다.

  • Function IsFileIncluded 이 함수는 지정된 파일 이름의 확장명이 스크립트로 처리되어 데이터베이스 프로젝트에 추가되어야 하는 파일의 확장명 목록에 있는지 여부를 확인합니다.

  • Function GetOutputWindowPane 이 함수는 진행률 메시지를 보고할 수 있도록 출력 창을 반환합니다.

  • Sub AddScriptsInDirectory2 이 서브루틴은 프로젝트 폴더와 경로를 사용하고 확장명이 스크립트 확장명 목록의 항목과 일치하는 모든 파일을 추가합니다.

  • Sub AddScriptsInDirectory 이 매크로의 입력 루틴에 해당하는 이 서브루틴은 전달된 매개 변수를 처리하고, 유효성 검사를 수행하며, 대상 폴더를 만들거나 폴더가 이미 있는 경우 데이터베이스 프로젝트에서 이를 검색합니다. 그런 다음 이 서브루틴은 AddScriptsInDirectory2를 호출하여 해당 폴더에 파일을 추가합니다.

AddScriptsInDirectory 매크로를 만들려면

  1. 매크로 탐색기에서 ImportScriptsExample 모듈을 마우스 오른쪽 단추로 클릭하고 편집을 클릭합니다.

    Microsoft Visual Studio Macros 창이 나타납니다. 이 창에는 ImportScriptsExample 모듈의 내용이 표시됩니다.

  2. 모듈의 내용을 다음 VBScript 코드로 대체합니다.

    Imports System
    Imports EnvDTE
    Imports EnvDTE80
    Imports System.Diagnostics
    
    Public Module ImportScriptsExample
        ' A list of folder names, file names, and extensions that we want to add
        '  to the solution.
        Dim outputWindowPaneTitle As String = "Add scripts to a project folder report"
        Dim includedExtensions As New System.Collections.Specialized.StringCollection
    
        ' Function to filter out folder names, file names, and extensions that we do not 
        '  want to add to the solution.
        Function IsFileIncluded(ByVal filePath As String) As Boolean
            Dim extension As String
            Dim fileName As String
    
            extension = System.IO.Path.GetExtension(filePath)
            extension = extension.ToLower()
    
            fileName = System.IO.Path.GetFileName(filePath)
            fileName = fileName.ToLower()
    
            If (includedExtensions.Contains(extension)) Then
                Return True
            Else
                If (includedExtensions.Contains(fileName)) Then
                    Return True
                Else
                    Return False
                End If
            End If
        End Function
    
        ' This function retrieves the output window pane
        Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
            Dim window As Window
            Dim outputWindow As OutputWindow
            Dim outputWindowPane As OutputWindowPane
    
            window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
            If show Then window.Visible = True
            outputWindow = window.Object
            Try
                outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
            Catch e As System.Exception
                outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
            End Try
            outputWindowPane.Activate()
            Return outputWindowPane
        End Function
    
        ' Given a folder within the solution and a folder on disk, add all files whose extensions
        ' are on a list of "good" extensions to the folder in the solution.
        Sub AddScriptsInDirectory2(ByVal newScriptFolder As ProjectItem, ByVal startFolder As String)
            Dim files As String()
            Dim file As String
            Dim folder As String
    
            ' get a list of files in the specified folder
            files = System.IO.Directory.GetFiles(startFolder)
    
            ' get the output window pane so we can report status
            Dim outputWindowPane As EnvDTE.OutputWindowPane
            outputWindowPane = GetOutputWindowPane(outputWindowPaneTitle, True)
    
            ' Examine all the files within the folder.
            For Each file In files
                ' if this file's extension is one we want to include...
                If (IsFileIncluded(file)) Then
                    ' try to add it to the folder
                    Dim projItem As ProjectItem
                    Try
                        projItem = newScriptFolder.ProjectItems().AddFromFile(file)
                        outputWindowPane.OutputString("The item """ + file + """ was added" + vbLf)
    
                        If (Not (projItem Is Nothing)) Then
                            If (Not (projItem.Document Is Nothing)) Then
                                projItem.Document.Close(vsSaveChanges.vsSaveChangesNo)
                            End If
                        End If
                    Catch
                        ' if an error occurs, report the failure
                        outputWindowPane.OutputString("The item """ + file + """may have not been added to the solution." + vbLf)
                    End Try
                End If
            Next
        End Sub
    
        ' creates a new subfolder within the Scripts folder in the specified database project
        ' then adds all files in the specified path to the newly created scripts sub-folder.
        Sub AddScriptsInDirectory(Optional ByVal dbProjName As String = "", Optional ByVal scriptFolderName As String = "", Optional ByVal startFolder As String = "")
            If (String.IsNullOrEmpty(dbProjName)) Then
                dbProjName = InputBox("Type the name of the database project to which you want the scripts to be imported.")
                If (String.IsNullOrEmpty(dbProjName)) Then
                    Return
                End If
            End If
    
            If (String.IsNullOrEmpty(scriptFolderName)) Then
                scriptFolderName = InputBox("Type the script folder name.")
                If (String.IsNullOrEmpty(scriptFolderName)) Then
                    scriptFolderName = "Scripts"
                End If
            End If
    
            If (String.IsNullOrEmpty(startFolder)) Then
                startFolder = InputBox("Type the folder path to import.")
                If (String.IsNullOrEmpty(startFolder)) Then
                    Return
                End If
            End If
    
            If (System.IO.Directory.Exists(startFolder) = False) Then
                MsgBox("The specified folder could not be found.")
                Return
            End If
    
            GetOutputWindowPane(outputWindowPaneTitle, True).Clear()
    
            If System.IO.Directory.Exists(startFolder) = False Then
                Dim outputWindowPane As EnvDTE.OutputWindowPane
                outputWindowPane = GetOutputWindowPane(outputWindowPaneTitle, True)
                outputWindowPane.OutputString("The path entered could not be found" + vbLf)
                Exit Sub
            End If
    
            includedExtensions = New System.Collections.Specialized.StringCollection
            ' If you do not want a file with a particular extension or name
            '  to be added, then add that extension or name to this list:
            includedExtensions.Add(".sql")
            includedExtensions.Add(".tsql")
    
            Dim newScriptFolder As ProjectItem
            Dim project As Project
    
            ' now check to see if the desired folder in the project already exists
            For Each project In DTE.Solution
                Dim projectItem As EnvDTE.ProjectItem
    
                If (dbProjName.Equals(project.Name)) Then
                    Dim found As Boolean
                    found = False
                    For Each projectItem In project.ProjectItems()
                        If (scriptFolderName.Equals(projectItem.Name)) Then
                            ' the desired folder already exists, save the projectItem that corresponds
                            ' to the folder.
                            found = True
                            newScriptFolder = projectItem
                        End If
                    Next
    
                    ' if the folder does not exist within the project, create it.
                    If (Not found) Then
                        ' the folder does not already exist, so create it
                        newScriptFolder = project.ProjectItems().AddFolder(scriptFolderName, EnvDTE.Constants.vsProjectItemKindPhysicalFolder)
                    End If
                End If
            Next
    
            ' now add the scripts in the folder to the project folder
            AddScriptsInDirectory2(newScriptFolder, startFolder)
        End Sub
    End Module
    
  3. 매크로 창에서 파일 메뉴를 열고 MyMacros 저장을 클릭합니다.

  4. 파일 메뉴에서 닫고 돌아가기를 클릭합니다.

    다음으로 매크로를 실행하여 결과를 나타냅니다.

ToggleTriggers 매크로 실행

이 연습에서 만든 솔루션이 아닌 다른 솔루션에서 매크로를 실행하는 경우 MyAdvWorks 대신 해당 솔루션에 들어 있는 데이터베이스 프로젝트의 이름을 지정해야 합니다.

명령 창에서 ToggleTriggers 매크로를 실행하려면

  1. 솔루션 탐색기에서 MyAdvWorks 데이터베이스 프로젝트를 확장합니다.

  2. 스키마 개체 폴더를 확장합니다.

  3. 테이블 폴더를 확장합니다.

  4. 트리거 폴더를 확장합니다.

  5. 솔루션 탐색기에서 아무 트리거나 오른쪽 마우스 단추로 클릭하고 속성을 클릭합니다.

    선택한 트리거의 빌드 작업 속성 값을 기록해 둡니다.

  6. 보기 메뉴에서 다른 창을 가리킨 다음 명령 창을 클릭합니다.

    명령 창이 나타납니다.

  7. 명령 창에서 다음을 입력합니다.

    Macros.MyMacros.BuildActionExample.ToggleTriggers MyAdvWorks
    

    MyAdvWorks는 해당 트리거의 빌드 작업 속성이 전환될 데이터베이스 프로젝트의 이름입니다.

  8. 매크로가 완료될 때까지 기다립니다.

  9. 매크로가 실행을 마치면 5단계의 트리거에 대한 속성을 확인합니다.

    빌드 작업 속성 값은 매크로를 실행하기 전의 값과 반대입니다.

    매크로를 다시 실행하면 빌드 작업 속성 값을 원래 상태로 복원할 수 있습니다.

    다음에는 매크로 탐색기에서 AddScriptsInDirectory 매크로를 실행합니다.

AddScriptsInDirectory 매크로 실행

이 연습에서 만든 솔루션이 아닌 다른 솔루션에서 매크로를 실행하는 경우 MyAdvWorks 대신 해당 솔루션에 들어 있는 데이터베이스 프로젝트의 이름을 지정해야 합니다.

매크로 탐색기에서 AddScriptsInDirectory 매크로를 실행하려면

  1. 매크로 탐색기가 열려 있지 않은 경우 보기 메뉴를 열고 다른 창을 가리킨 후 매크로 탐색기를 클릭합니다.

    매크로 탐색기가 나타납니다.

  2. 매크로 탐색기에서 AddScriptsInDirectory(매크로를 표시하기 위해 ImportScriptsExample 모듈을 확장해야 할 수 있음)를 마우스 오른쪽 단추로 클릭하고 실행을 클릭합니다.

    Visual Studio 매크로 대화 상자가 나타나면서 "Type the name of the database project to which you want the scripts to be imported."라는 메시지가 표시됩니다.

  3. MyAdvWorks를 입력하고 확인을 클릭합니다.

    Visual Studio 매크로 대화 상자가 다시 나타나면서 "Type the script folder name."이라는 메시지가 표시됩니다.

  4. 확인을 클릭하여 스크립트 폴더에 스크립트를 추가하는 기본 동작을 허용합니다.

    Visual Studio 매크로 대화 상자가 다시 나타나면서 "Type the folder path to import."라는 메시지가 표시됩니다.

  5. 스크립트 파일이 있는 경로를 이 항목 앞부분의 필수 구성 요소 단원에 나와 있는 대로 입력합니다. 예를 들어 스크립트가 C:\Temp에 있는 경우 C:\Temp를 입력한 후 확인을 클릭합니다.

    매크로는 확장명이 .sql 또는 .tsql인 파일이 MyAdvWorks 데이터베이스 프로젝트의 스크립트 폴더에 추가될 때까지 계속 실행됩니다.

다음 단계

이 연습에서는 데이터베이스 프로젝트에서 Visual Studio 자동화 모델을 사용하여 수행할 수 있는 간단한 샘플 작업을 살펴보았습니다. 보다 높은 융통성이 요구되는 경우에는 Visual Studio 추가 기능의 자동화 모델을 사용할 수도 있습니다.

참고 항목

개념

프로젝트 확장성 소개

Database Edition의 용어 개요

기타 리소스

Visual Studio 매크로

추가 기능 및 마법사 만들기

자동화 어셈블리 및 DTE2 개체 참조