4df0db4c6b3c4109a8a6b232727bf2f1

Porównywanie struktury i wykrywanie zmian pomiędzy bazami danych

Wprowadzenie

Porównywanie struktury i wykrywanie zmian pomiędzy bazami danych wydaje się problemem dość powszechnym. Motywacja może być skrajnie różna, ale jako przykład można podać:

  • Sprawdzanie zmian pomiędzy projektem bazy danych oraz samą bazą danych przed jej aktualizacjom
  • Sprawdzenie zmian pomiędzy dwiema różnymi bazami danych
  • Sprawdzanie aktualnej struktury bazy danych z projektem w celu wykrycia manualnych zmian w bazie danych

Scenariusze te mogą wynikać czy to z przygotowania procesu publikacji zmian czy też zapewnienia odpowiedniej higieny bazy danych. Trzeba pamiętać, że w przypadku rozwiązań hurtowni danych dość często spotkać można różne “tymczasowe” obiekty, takie jak tabele z kopią danych przed przeładowaniem danych czy też różne wersje procedur, które tworzy programista w trakcie testowania ich wydajności. Wraz z upływem czasu ilość takich obiektów może być całkiem spora… Oczywiście powinien istnieć projekt bazy danych, nikt nie powinien wprowadzać manualnie żadnych zmian bezpośrednio na bazie danych, a projekt bazy danych powinien być publikowany bez jakiejkolwiek ingerencji użytkownika z wykorzystaniem narzędzi i procesów “Continiuus Integration”. Niestety przeważnie przynajmniej jeden z tych punktów okazuje się prawdą i wtedy też albo manualnie, albo najlepiej automatycznie jesteśmy zmuszeni do porównania dwóch baz danych lub bazy danych z projektem. W dzisiejszym poście postaram się przybliżyć różne metody oraz narzędzia, z których możemy skorzystać, aby to osiągnąć w przypadku SQL Server.

  1. Przedstawienie problemu

    Skrypt bazy danych w tym przykładzie nie ma większego znaczenia, natomiast w celach poglądowych załóżmy, że posiadamy projekt bazy danych z następującą strukturą:

    use master;
    
    go
    
    drop database if exists demo_compare_1
    
    go
    
    
    create database demo_compare_1
    
    go
    
    use demo_compare_1
    
    go
    
    drop table if exists dbo.table1
    
    go
    
    create table dbo.table1
    (
    	id int identity(1,1),
    	value1 int,
    	value2 varchar(20),
    	value3 datetime default (getdate())
    )
    
    go
    
    drop table if exists dbo.table2
    
    go
    
    create table dbo.table2
    (
    	id int identity(1,1),
    	value1 int
    )
    
    go
    
    create table dbo.table3
    (
    	id int identity(1,1),
    	value1 int
    )
    
    go
    
    drop view if exists dbo.view1
    
    go
    
    create view dbo.view1 
    as
    select id, value1 from dbo.table1
    
    go
    
    create procedure dbo.sp1
    (
    @param1 int,
    @param2 varchar(10)
    )
    as
    insert into dbo.table1 (value1, value2) values (@param1, @param2)
    

    oraz bazę danych na serwerze z następującą strukturą:

    use master;
    
    go
    
    drop database if exists demo_compare_2
    
    go
    
    
    create database demo_compare_2
    
    go
    
    use demo_compare_2
    
    go
    
    drop table if exists dbo.table1
    
    go
    
    create table dbo.table1
    (
    	id int identity(1,1),
    	value1 int,
    	value2 varchar(20),
    	value3 datetime
    )
    
    go
    
    drop table if exists dbo.table2
    
    go
    
    create table dbo.table2
    (
    	id int identity(1,1),
    	value1 int,
    	value2 varchar(20)
    )
    
    go
    
    drop view if exists dbo.view1
    
    go
    
    create view dbo.view1 
    as
    select id, value1 from dbo.table1
    
    go
    
    create view dbo.view2
    as
    select id, value1 from dbo.table2
    
    go
    
    create procedure dbo.sp1
    (
    @param1 int,
    @param2 varchar(10)
    )
    as
    insert into dbo.table1 (value1, value2) values (@param1, @param2)
    

    Jak widać na powyższych skryptach struktura obu baz danych jest dość trywialna, natomiast bazy te nieznacznie się różnią. W projekcie dodaną nową tabelę, natomiast zmianie uległa również sama baza danych znajdująca się na serwerze. Obrazuje to natomiast ideę problemu, jaki może się pojawić.

  2. Proste porównywanie z wykorzystaniem zapytań w T-SQL

    W przypadku porównywania dwóch baz danych, które znajdują się na serwerze najprostszą metodą może okazać się skorzystanie z widoków systemowych, które za pomocą T-SQL pozwolą wyekstrahować strukturę obu baz danych i za pomocą prostego zapytania pozwoli znaleźć różnicę pomiędzy nimi. Przykładowo:

    -- compare two databases, same server
    
    drop table if exists #demo_compare_1
    drop table if exists #demo_compare_2
    
    select 
    	'SchemaName'		= s.name, 
    	'TableName'			= t.name
    into #demo_compare_1
    from demo_compare_1.sys.schemas s
    inner join demo_compare_1.sys.tables t
    	on s.schema_id = t.schema_id
    
    select 
    	'SchemaName'		= s.name, 
    	'TableName'			= t.name
    into #demo_compare_2
    from demo_compare_2.sys.schemas s
    inner join demo_compare_2.sys.tables t
    	on s.schema_id = t.schema_id
    
    
    select 'demo_compare_1' as DatabaseName, * from
    (
    	select * from #demo_compare_1
    	except 
    	select * from #demo_compare_2
    ) x1
    union all
    select 'demo_compare_2' as DatabaseName, * from
    (
    	select * from #demo_compare_2
    	except 
    	select * from #demo_compare_1
    ) x1

    Powyższy skrypt pozwoli wykryć różnice w ilości oraz strukturze tabel. Oczywiście skrypt powinien być rozszerzony przynajmniej o typy danych kolumn, klucze czy też indeksy dla tabel oraz o pobieranie informacji o pozostałych obiektach (widoki, procedury, etc) w celu bardziej szczegółowego porównania. Plusem takiego rozwiązania niewątpliwie jest prostota oraz fakt, że jest to tak naprawdę jeden skrypt T-SQL. Jeżeli bazy znajdują się na różnych serwerach można skorzystać z “Linked Servers” czy też przygotować prosty projekt w “SQL Server Integration Services”. Z całą pewnością nie jest to jednak wydajna i polecana opcja szczególnie dla większych projektów.

  3. Wykrywanie zmian z wykorzystaniem Visual Studio

    “Visual Studio” w ramach projektu bazy danych dostarcza narzędzie “Schema Compare”, które pozwala w bardzo prosty sposób porównać bieżący projekt bazy danych z bazą danych na serwerze,ale również między innymi dwie różne bazy danych znajdujące się na różnych serwerach.

    Wynikiem operacji jest szczegółowy raport ze zmianami pomiędzy dwiema bazami.

    Dodatkowo w prosty sposób można wygenerować skrypt różnicowy i zaktualizować bazę danych lub projekt zgodnie z oczekiwaniami. Co ważne “Visual Studio” w tym przypadku korzysta z narzędzi i bibliotek, które można również wykonać z poziomu linii poleceń co zostanie pokazane w następnych akapitach.

  4. Wykrywanie zmian z wykorzystaniem tablediff

    “Tablediff” (https://docs.microsoft.com/en-us/sql/tools/tablediff-utility?view=sql-server-2017) to narzędzie, które de facto nie służy do porównywania struktury bazy danych, ale myślę, że warto o nim tutaj wspomnieć. Służy on do porównywania zawartości (danych) pomiędzy dwoma tabelami. Gdy spróbujemy porównać dwie tabele, które nie są identyczne otrzymamy błąd. Przykładowo:

    "C:\Program Files\Microsoft SQL Server\140\COM\tablediff.exe" -sourceserver "demo\sql2017" -sourcedatabase demo_compare_1 -sourcetable table1 -destinationserver "demo\sql2017" -destinationdatabase demo_compare_2 -destinationtable table2 -et Difference

    Zwróci następujący komunikat:

    Table [demo_compare_1].[dbo].[table1] on demo\sql2017 and Table [demo_compare_2].[dbo].[table2] on demo\sql2017 have different schemas and cannot be compared.
    The requested operation took 0.7362781 seconds.

    Poprawne wykonanie komendy zwróci natomiast następujący komunikat w sytuacji, gdy tabele będą identyczne (zarówno pod względem struktury jak i danych)

    Table [demo_compare_1].[dbo].[table1] on demo\sql2017 and Table [demo_compare_2].[dbo].[table1] on demo\sql2017 are identical.
    The requested operation took 0.7382033 seconds.

    Dodatkowo za pomocą dodatkowych parametrów można wpłynąć na zwracany rezultat, w tym przypadku parametr “et” oraz “f” pozwoli na wygenerowanie skryptu, który zadba o doprowadzenie drugiej tabeli do takiego samego stanu (pod względem danych)

    "C:\Program Files\Microsoft SQL Server\140\COM\tablediff.exe" -sourceserver "demo\sql2017" -sourcedatabase demo_compare_1 -sourcetable table1 -destinationserver "demo\sql2017" -destinationdatabase demo_compare_2 -destinationtable table1 -et Difference -f "c:\temp\tablediff.sql"

    Przykładowy rezultat:

    -- Host: demo\sql2017
    -- Database: [demo_compare_2]
    -- Table: [dbo].[table1]
    SET IDENTITY_INSERT [dbo].[table1] ON
    INSERT INTO [dbo].[table1] ([id],[value1],[value2],[value3]) VALUES (1,0,N'0',N'1900-01-01 00:00:00.000')
    INSERT INTO [dbo].[table1] ([id],[value1],[value2],[value3]) VALUES (2,1,N'1',N'1900-01-02 00:00:00.000')
    SET IDENTITY_INSERT [dbo].[table1] OFF
    

    Jak wspomniałem nie jest to narzędzie do porównywania schematu, natomiast pośrednio również zwraca informację o tym czy schemat pomiędzy dwoma tabelami jest identyczny.

  5. Wykrywanie zmian z wykorzystaniem sqlpackage

    Kolejnym przykładem narzędzia jest “sqlpackage” (https://docs.microsoft.com/en-us/sql/tools/sqlpackage?view=sql-server-2017). Pozwala ono na szereg operacji związanych z pracą z projektem baz danych, cyklem życia bazy danych, a w szczególności z bazami danych zarejestrowanymi jako “data tier application” (https://docs.microsoft.com/en-us/sql/relational-databases/data-tier-applications/data-tier-applications?view=sql-server-2017), ale nie tylko.

    1. DriftReport
      Pierwszą z opcji narzędzia jest opcja “DriftReport”, która pozwala na wykrycie zmian w bazie danych od czasu jej ostatniej publikacji. W celu skorzystania z tej opcji baza danych musi jednak być zarejestrowana jako “Data-tier application”. Wtedy bowiem, kopia projektu bazy danych (“DACPAC”) jest składowana na serwerze bazy danych i w chwili wykonania polecenia jest ona porównywana z aktualną strukturą bazy danych. Przykładowo:

      "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\sqlpackage.exe" /action:DriftReport /TargetConnectionString:"server=demo\sql2017; database=demo_compare_1;trusted_connection=True" /OutputPath:"C:\temp\drift.xml"

      Rezultatem będzie plik z opisem zmian:

      <DriftReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DriftReport/2012/02">
        <Additions>
          <Object Name="[table4]" Parent="[dbo]" Type="SqlTable" />
          <Object Name="[value2]" Parent="[dbo].[table3]" Type="SqlSimpleColumn" />
        </Additions>
        <Removals>
          <Object Name="[@param1]" Parent="[dbo].[sp1]" Type="SqlSubroutineParameter" />
        </Removals>
        <Modifications>
          <Object Name="[sp1]" Parent="[dbo]" Type="SqlProcedure" />
          <Object Name="[table3]" Parent="[dbo]" Type="SqlTable" />
        </Modifications>
      </DriftReport>

      Jest to świetne narzędzie do wykrywania obiektów, które zostały manualnie dodane lub zmienione bezpośrednio na serwerze. Pewnym minusem natomiast może być fakt, że baza danych musi być zarejestrowana jako “Data-Tier application”. Warto również dodać, że korzystając z projektu bazy danych, jeżeli baza danych jest zarejestrowana, można skorzystać z opcji “Block publish when database has drifted from registered version”, która przerwie publikowanie w chwili wykrycia zmian. Czasami jednak musimy pogodzić się z faktem, że baza danych może zawierać pewne obiekty, które pełnią rolę kopii tymczasowych. Szczególnie w przypadku rozwiązań hurtowni danych.

    2. DeployReport
      Kolejną opcją “sqlpackage” jest “DeployReport”. Pozwala ona na porównanie projektu bazy danych z bazą danych na serwerze oraz wygenerowanie podsumowania z informacją, które obiekty zostaną opublikowane podczas publikacji zmian. Niestety nie ma możliwości porównania dwóch baz danych, a taka próba:

      "C:\Program Files (x86)\Microsoft Visual Studio\2017\SQL\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\150\sqlpackage.exe" /action:DeployReport /TargetConnectionString:"server=demo\sql2017; database=demo_compare_1;trusted_connection=True" /SourceConnectionString:"server=demo\sql2017; database=demo_compare_2;trusted_connection=True" /OutputPath:"C:\temp\drift_2.xml"

      Zwróci błąd:

      *** Operation DeployReport does not support source and target being a database.

      Dozwolone natomiast jest porównywanie pliku projektu (pliku bazy danych DACPAC) z bazą danych na serwerze. Co ważne można korzystać z profilu publikacji co ułatwia pracę z wieloma środowiskami oraz parametrami.

      "C:\Program Files (x86)\Microsoft Visual Studio\2017\SQL\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\150\sqlpackage.exe" /action:DeployReport /TargetConnectionString:"server=demo\sql2017; database=demo_compare_1;trusted_connection=True" /SourceFile:"C:\Users\sdrzymala\Desktop\schema-compare\db-project\Database\Database\bin\Debug\Database.dacpac" /Variables:variable1="value1" /OutputPath:"C:\temp\deployreport.xml"

      Z wykorzystaniem profilu publikacji:

      "C:\Program Files (x86)\Microsoft Visual Studio\2017\SQL\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\150\sqlpackage.exe" /action:DeployReport /TargetConnectionString:"server=demo\sql2017; database=demo_compare_1;trusted_connection=True" /SourceFile:"C:\Users\sdrzymala\Desktop\schema-compare\db-project\Database\Database\bin\Debug\Database.dacpac" /Profile:"C:\Users\sdrzymala\Desktop\schema-compare\db-project\Database\Database\Database.publish.xml" /OutputPath:"C:\temp\deployreport.xml"

      Przykładowy rezultat:

      <?xml version="1.0" encoding="utf-8"?>
      <DeploymentReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02">
          <Alerts>
              <Alert Name="DataIssue">
                  <Issue Value="The column [dbo].[table3].[value2] is being dropped, data loss could occur." Id="1" />
              </Alert>
          </Alerts>
          <Operations>
              <Operation Name="Alter">
                  <Item Value="[dbo].[table3]" Type="SqlTable">
                      <Issue Id="1" />
                  </Item>
                  <Item Value="[dbo].[sp1]" Type="SqlProcedure" />
              </Operation>
          </Operations>
      </DeploymentReport>

      Należy pamiętać, że domyślnie polecenie nie zwróci obiektów, które zostały manualnie dodane do bazy danych na serwerze. Problem ten można rozwiązać modyfikując profil publikacji oraz zaznaczając opcję w “Advanced > Drop: “Drop objects in target but not in source”. Rezultat:

      <?xml version="1.0" encoding="utf-8"?>
      <DeploymentReport xmlns="http://schemas.microsoft.com/sqlserver/dac/DeployReport/2012/02">
          <Alerts>
              <Alert Name="DataIssue">
                  <Issue Value="The column [dbo].[table3].[value2] is being dropped, data loss could occur." Id="1" />
                  <Issue Value="The table [dbo].[table4] is being dropped, data loss could occur." Id="2" />
              </Alert>
          </Alerts>
          <Operations>
              <Operation Name="Drop">
                  <Item Value="Permission" Type="SqlPermissionStatement" />
                  <Item Value="Permission" Type="SqlPermissionStatement" />
                  <Item Value="[dbo].[table4]" Type="SqlTable">
                      <Issue Id="2" />
                  </Item>
              </Operation>
              <Operation Name="Alter">
                  <Item Value="[dbo].[table3]" Type="SqlTable">
                      <Issue Id="1" />
                  </Item>
                  <Item Value="[dbo].[sp1]" Type="SqlProcedure" />
              </Operation>
          </Operations>
      </DeploymentReport>

      W tym przypadku komenda zwróci również listę obiektów, które znajdują się w bazie danych, natomiast nie znajdują się w projekcie. Niestety nie ma tutaj jawnego rozróżnienia pomiędzy tymi obiektami. Oczywiście powyższe ustawienie nie zawsze się sprawdzi, natomiast zawsze pozostaje opcja przygotowania dedykowanego profilu do tego typu porównań.

    3. Extract
      Ostatnią opcją “sqlpackage” o której chciałbym tutaj wspomnieć jest “Extract”. Przykład:

      "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\130\sqlpackage.exe" /a:Extract /SourceConnectionString:"server=demo\sql2017; database=demo_compare_1;trusted_connection=True"; /targetfile:"C:\temp\mydacpac.dacpac"

      Opcja “Extract” pozwala na wygenerowanie pliku bazy danych (“DACPAC”) z istniejącej bazy danych znajdującej się na serwerze. Co ważne baza nie musi być zarejestrowana jako “Data-Tier application”. Może to być bardzo przydatna opcja między innymi w przypadku korzystania z następnego narzędzia.

  6. Wykrywanie zmian z wykorzystaniem msbuild

    Kolejnym narzędziem, który możemy wykorzystać jest “msbuild” (https://blogs.msdn.microsoft.com/ssdt/2014/07/15/msbuild-support-for-schema-compare-is-available/). Korzystając z opcji “SqlSchemaCompare” jesteśmy w stanie porównać bazy danych oraz pliki projektów bazy danych (“DACPAC”). Niestety ja miałem sporo problemów z uruchomieniem polecenia oraz porównaniem z bazą danych bezpośrednio i polecenie, które teoretycznie powinno działać, w moim przypadku nie zawsze działa – na przykład w SQL Server 2017:

    "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "C:\temp\proj.csproj" /p:TargetDatabaseName=demo_compare_1;TargetConnectionString="Data Source=demo\sql2017;Integrated Security=True;Pooling=False" /t:SqlSchemaCompare /p:source="C:\Users\sdrzymala\Desktop\schema-compare\db-project\Database\Database\bin\Debug\Database.dacpac" /p:XmlOutput="C:\temp\\output.xml" /p:Deploy="false"

    Natomiast porównywanie dwóch plików “DACPAC” działa bez zarzutów. Tutaj można wykorzystać “sqlpackage” (opcja “Extract”) oraz wygenerować “DACPAC” w celu porównania z projektem. Przykładowo:

    "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" "C:\temp\proj.csproj" /t:SqlSchemaCompare /p:source="C:\temp\demo_compare_1.dacpac" /p:target="C:\temp\demo_compare_1.dacpac" /p:XmlOutput="C:\temp\output.xml" /p:Deploy="false"

    Rezultat:

    <?xml version="1.0" encoding="utf-16"?>
    <Result GroupBy="by action">
    	<Group Value="Delete">
    		<Entry Update="Delete" Name="View" Type="TopLevelElement">
    			<Source />
    			<Target>dbo.view2</Target>
    			<OrderChanged>False</OrderChanged>
    			<Ordinal>0</Ordinal>
    			<ContainsOrderChanged>False</ContainsOrderChanged>
    			<SiblingOrderChanged>False</SiblingOrderChanged>
    			<Refactored>False</Refactored>
    			<ChildRefactored>False</ChildRefactored>
    			<InclusionState>Included</InclusionState>
    			<Children>
    				<Entry Update="Delete" Name="Columns" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Delete" Name="Computed Column" Type="Element">
    							<Source />
    							<Target>dbo.view2.id</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    							<Children>
    								<Entry Update="Delete" Name="ExpressionDependencies" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Delete" Name="Column" Type="Property">
    											<Source />
    											<Target>dbo.table2.id</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    								<Entry Update="Delete" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Delete" Name="ExpressionScript" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsPersisted" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsPersistedNullable" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    						<Entry Update="Delete" Name="Computed Column" Type="Element">
    							<Source />
    							<Target>dbo.view2.value1</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    							<Children>
    								<Entry Update="Delete" Name="ExpressionDependencies" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Delete" Name="Column" Type="Property">
    											<Source />
    											<Target>dbo.table2.value1</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    								<Entry Update="Delete" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Delete" Name="ExpressionScript" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsPersisted" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsPersistedNullable" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    					</Children>
    				</Entry>
    				<Entry Update="Delete" Name="Properties" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Delete" Name="IsAnsiNullsOn" Type="Property">
    							<Source />
    							<Target>True</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsColumnExplicitlyDefined" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsEncrypted" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsMetadataReported" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsQuotedIdentifierOn" Type="Property">
    							<Source />
    							<Target>True</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsReplicated" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsSchemaBound" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="IsWithCheckOption" Type="Property">
    							<Source />
    							<Target>False</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="QueryScript" Type="Property">
    							<Source />
    							<Target>
    select id, value1 from dbo.table2</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    					</Children>
    				</Entry>
    				<Entry Update="Delete" Name="QueryDependencies" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Delete" Name="Column" Type="Property">
    							<Source />
    							<Target>dbo.table2.id</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="Column" Type="Property">
    							<Source />
    							<Target>dbo.table2.value1</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Delete" Name="Table" Type="Property">
    							<Source />
    							<Target>dbo.table2</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    					</Children>
    				</Entry>
    			</Children>
    		</Entry>
    	</Group>
    	<Group Value="Change">
    		<Entry Update="Change" Name="Table" Type="TopLevelElement">
    			<Source>dbo.table1</Source>
    			<Target>dbo.table1</Target>
    			<OrderChanged>False</OrderChanged>
    			<Ordinal>0</Ordinal>
    			<ContainsOrderChanged>False</ContainsOrderChanged>
    			<SiblingOrderChanged>False</SiblingOrderChanged>
    			<Refactored>False</Refactored>
    			<ChildRefactored>False</ChildRefactored>
    			<InclusionState>Included</InclusionState>
    			<Children>
    				<Entry Update="Add" Name="Default Constraint" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>Included</InclusionState>
    					<Children>
    						<Entry Update="Add" Name="Default Constraint" Type="Element">
    							<Source>unnamed constraint on dbo.table1</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>Included</InclusionState>
    							<Children>
    								<Entry Update="Add" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Add" Name="DefaultExpressionScript" Type="Property">
    											<Source>(getdate())</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="ForColumn" Type="Property">
    											<Source>dbo.table1.value3</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsDisabled" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsWithValues" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    					</Children>
    				</Entry>
    			</Children>
    		</Entry>
    		<Entry Update="Change" Name="Table" Type="TopLevelElement">
    			<Source>dbo.table2</Source>
    			<Target>dbo.table2</Target>
    			<OrderChanged>False</OrderChanged>
    			<Ordinal>0</Ordinal>
    			<ContainsOrderChanged>False</ContainsOrderChanged>
    			<SiblingOrderChanged>False</SiblingOrderChanged>
    			<Refactored>False</Refactored>
    			<ChildRefactored>False</ChildRefactored>
    			<InclusionState>Included</InclusionState>
    			<Children>
    				<Entry Update="Delete" Name="Columns" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Delete" Name="Column" Type="Element">
    							<Source />
    							<Target>dbo.table2.value2</Target>
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    							<Children>
    								<Entry Update="Delete" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Delete" Name="Collation" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="EncryptionAlgorithmName" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="EncryptionType" Type="Property">
    											<Source />
    											<Target>0</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="GeneratedAlwaysType" Type="Property">
    											<Source />
    											<Target>0</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IdentityIncrement" Type="Property">
    											<Source />
    											<Target>1</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IdentityIsNotForReplication" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IdentitySeed" Type="Property">
    											<Source />
    											<Target>1</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsFileStream" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsHidden" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsIdentity" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsMax" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsNullable" Type="Property">
    											<Source />
    											<Target>True</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsRowGuidColumn" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="IsSparse" Type="Property">
    											<Source />
    											<Target>False</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="Length" Type="Property">
    											<Source />
    											<Target>20</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="MaskingFunction" Type="Property">
    											<Source />
    											<Target>null</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="Precision" Type="Property">
    											<Source />
    											<Target>0</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="Scale" Type="Property">
    											<Source />
    											<Target>0</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Delete" Name="Type" Type="Property">
    											<Source />
    											<Target>varchar</Target>
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    					</Children>
    				</Entry>
    			</Children>
    		</Entry>
    	</Group>
    	<Group Value="Add">
    		<Entry Update="Add" Name="Table" Type="TopLevelElement">
    			<Source>dbo.table3</Source>
    			<Target />
    			<OrderChanged>False</OrderChanged>
    			<Ordinal>0</Ordinal>
    			<ContainsOrderChanged>False</ContainsOrderChanged>
    			<SiblingOrderChanged>False</SiblingOrderChanged>
    			<Refactored>False</Refactored>
    			<ChildRefactored>False</ChildRefactored>
    			<InclusionState>Included</InclusionState>
    			<Children>
    				<Entry Update="Add" Name="Columns" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Add" Name="Column" Type="Element">
    							<Source>dbo.table3.id</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>0</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    							<Children>
    								<Entry Update="Add" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Add" Name="Collation" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="EncryptionAlgorithmName" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="EncryptionType" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="GeneratedAlwaysType" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentityIncrement" Type="Property">
    											<Source>1</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentityIsNotForReplication" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentitySeed" Type="Property">
    											<Source>1</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsFileStream" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsHidden" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsIdentity" Type="Property">
    											<Source>True</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsMax" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsNullable" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsRowGuidColumn" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsSparse" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Length" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="MaskingFunction" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Precision" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Scale" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Type" Type="Property">
    											<Source>int</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    						<Entry Update="Add" Name="Column" Type="Element">
    							<Source>dbo.table3.value1</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>1</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    							<Children>
    								<Entry Update="Add" Name="Properties" Type="Folder">
    									<Source />
    									<Target />
    									<OrderChanged>False</OrderChanged>
    									<Ordinal>2147483647</Ordinal>
    									<ContainsOrderChanged>False</ContainsOrderChanged>
    									<SiblingOrderChanged>False</SiblingOrderChanged>
    									<Refactored>False</Refactored>
    									<ChildRefactored>False</ChildRefactored>
    									<InclusionState>None</InclusionState>
    									<Children>
    										<Entry Update="Add" Name="Collation" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="EncryptionAlgorithmName" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="EncryptionType" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="GeneratedAlwaysType" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentityIncrement" Type="Property">
    											<Source>1</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentityIsNotForReplication" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IdentitySeed" Type="Property">
    											<Source>1</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsFileStream" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsHidden" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsIdentity" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsMax" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsNullable" Type="Property">
    											<Source>True</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsRowGuidColumn" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="IsSparse" Type="Property">
    											<Source>False</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Length" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="MaskingFunction" Type="Property">
    											<Source>null</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Precision" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Scale" Type="Property">
    											<Source>0</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    										<Entry Update="Add" Name="Type" Type="Property">
    											<Source>int</Source>
    											<Target />
    											<OrderChanged>False</OrderChanged>
    											<Ordinal>2147483647</Ordinal>
    											<ContainsOrderChanged>False</ContainsOrderChanged>
    											<SiblingOrderChanged>False</SiblingOrderChanged>
    											<Refactored>False</Refactored>
    											<ChildRefactored>False</ChildRefactored>
    											<InclusionState>None</InclusionState>
    										</Entry>
    									</Children>
    								</Entry>
    							</Children>
    						</Entry>
    					</Children>
    				</Entry>
    				<Entry Update="Add" Name="Properties" Type="Folder">
    					<Source />
    					<Target />
    					<OrderChanged>False</OrderChanged>
    					<Ordinal>2147483647</Ordinal>
    					<ContainsOrderChanged>False</ContainsOrderChanged>
    					<SiblingOrderChanged>False</SiblingOrderChanged>
    					<Refactored>False</Refactored>
    					<ChildRefactored>False</ChildRefactored>
    					<InclusionState>None</InclusionState>
    					<Children>
    						<Entry Update="Add" Name="Durability" Type="Property">
    							<Source>0</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsAnsiNullsOn" Type="Property">
    							<Source>True</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsAutoGeneratedHistoryTable" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsChangeDataCaptureOn" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsChangeTrackingOn" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsFileStreamNull" Type="Property">
    							<Source>null</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsLargeValueTypesOutOfRow" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsMemoryOptimized" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsQuotedIdentifierOn" Type="Property">
    							<Source>True</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsReplicated" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsTableLockOnBulkLoad" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsTrackColumnsUpdatedOn" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="IsVardecimalStorageFormatOn" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="LockEscalation" Type="Property">
    							<Source>0</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="RemoteDataEnabled" Type="Property">
    							<Source>False</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>Excluded</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="RetentionUnit" Type="Property">
    							<Source>-2</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="RetentionValue" Type="Property">
    							<Source>-1</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    						<Entry Update="Add" Name="TextInRowSize" Type="Property">
    							<Source>0</Source>
    							<Target />
    							<OrderChanged>False</OrderChanged>
    							<Ordinal>2147483647</Ordinal>
    							<ContainsOrderChanged>False</ContainsOrderChanged>
    							<SiblingOrderChanged>False</SiblingOrderChanged>
    							<Refactored>False</Refactored>
    							<ChildRefactored>False</ChildRefactored>
    							<InclusionState>None</InclusionState>
    						</Entry>
    					</Children>
    				</Entry>
    			</Children>
    		</Entry>
    	</Group>
    </Result>

    Wynik jest zatem bardzo podobny, aczkolwiek bardziej szczegółowy…

  7. Wykrywanie zmian z wykorzystaniem dodatkowych narzędzi

    Na samym końcu należy wspomnieć o dodatkowych narzędziach, które można w tym celu wykorzystać. Mimo że w większości są one płatne to w większych projektach oraz większych zespołach przyśpieszają oraz upraszczają programowanie. Osobiście korzystałem z narzędzi RedGate, które mimo że są kosztowne to według mnie naprawdę są warte tej ceny (materiał niesponsorowany). Z pozostałych poniżej nie korzystałem, natomiast każdy z nich ma również spore grono zwolenników. Najpopularniejszymi narzędziami wydają się być:
    – RedGate SQLCompare (https://www.red-gate.com/products/sql-development/sql-compare/index)
    – DBComparer (https://dbcomparer.com/)
    – ApexSQL Diff (https://www.apexsql.com/sql_tools_diff.aspx)
    Oczywiście podobnych narzędzi jest znacznie więcej i dają podobne rezultaty, więc jeżeli tylko polityka firmy oraz budżet na to pozwolą to ich wykorzystanie wydaje się uzasadnione.

Zakończenie

Metod porównywania oraz wykrywania zmian czy to pomiędzy bazami danych czy też pomiędzy projektem bazy danych, a samą bazą danych jest stosunkowo wiele. Z wykorzystaniem “SQL Server Integration Services”, “SQL Agent”, “Windows Scheduler” czy też narzędzi do integracji oraz “Continiuus Integration/Delivery”, oprócz samego wykrywania zmian można ten proces również zautomatyzować. Należy dodać, że oczywiście warto dążyć do jak najlepszego kodu oraz dobre praktyki powinny zniwelować użycie powyższych narzędzi, natomiast jeżeli problem istnieje to, jak widać, narzędzi jest całkiem sporo. Zarówno płatnych, ale również darmowych.

PS1. Ścieżki do narzędzi mogą znajdować się w innych lokalizacjach, zgodnie z zainstalowaną wersją SQL Server.
PS2. Oczywiście “sqlpackage” posiada jeszcze kilka innych opcji, w tym między innymi “Deploy”, natomiast jest to poza zakresem tego postu. Podobnie wygląda sprawa “msbuild”

Slawomir Drzymala
Follow me on

2 Comments

  1. Witam. SchemaCompare jest dość wygodnym narzędziem. Jednak mam pewne problemy przy generowaniu skryptu, gdy chcę dane zmiany wprowadzić do bazy.
    Jeden z problemów to pojawienie się komunikatu “Target schema drift detected”. Zaraz po nim muszę ponownie wykonać Compare i potem wygenerować skrypt ponownie.
    Drugi to pojawienie się informacji o skutecznym wygenerowaniu kodu, jednak okno z kodem nie pojawia się.
    Czym te problemy mogą być to spowodowane?

    • Cześć.
      Pierwszy problem może wynikać na przykład z ustawień bazy danych/profilu np. ustawienia “Block publish when database has drifted from registred version”, chociaż google pokazuje, że przyczyna może być nawet nie związana z samym projektem bazy danych.
      Wydaje mi się, że żeby określić źródło problemów potrzebne będzie więcej informacji jak wersja Visual Studio, ustawienia bazy danych, ustawienia profilu itd. Jeżeli nie uda się rozwiązać problemu zapraszam do kontaktu mailowego gdzie chętnie spróbuję pomóc.

Leave a Reply