239 lines
8.9 KiB
C#
239 lines
8.9 KiB
C#
<Query Kind="Program">
|
|
<Connection>
|
|
<ID>77b65bea-e766-4e3c-a1ed-c4c2534b6019</ID>
|
|
<Persist>true</Persist>
|
|
<Server>D0001-SQL-11.sdt.local</Server>
|
|
<Database>jazz dev master Prod</Database>
|
|
<ShowServer>true</ShowServer>
|
|
</Connection>
|
|
<Reference><ProgramFilesX64>\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\Newtonsoft.Json.dll</Reference>
|
|
<NuGetReference>Amazon.Lambda.S3Events</NuGetReference>
|
|
<NuGetReference>AWSSDK.Core</NuGetReference>
|
|
<NuGetReference>AWSSDK.S3</NuGetReference>
|
|
<Namespace>Amazon</Namespace>
|
|
<Namespace>Amazon.Auth.AccessControlPolicy</Namespace>
|
|
<Namespace>Amazon.Auth.AccessControlPolicy.ActionIdentifiers</Namespace>
|
|
<Namespace>Amazon.Internal</Namespace>
|
|
<Namespace>Amazon.Lambda.S3Events</Namespace>
|
|
<Namespace>Amazon.MissingTypes</Namespace>
|
|
<Namespace>Amazon.Runtime</Namespace>
|
|
<Namespace>Amazon.Runtime.CredentialManagement</Namespace>
|
|
<Namespace>Amazon.Runtime.CredentialManagement.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.EventStreams</Namespace>
|
|
<Namespace>Amazon.Runtime.EventStreams.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Auth</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Settings</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Transform</Namespace>
|
|
<Namespace>Amazon.Runtime.Internal.Util</Namespace>
|
|
<Namespace>Amazon.Runtime.SharedInterfaces</Namespace>
|
|
<Namespace>Amazon.Runtime.SharedInterfaces.Internal</Namespace>
|
|
<Namespace>Amazon.S3</Namespace>
|
|
<Namespace>Amazon.S3.Encryption</Namespace>
|
|
<Namespace>Amazon.S3.Encryption.Internal</Namespace>
|
|
<Namespace>Amazon.S3.Internal</Namespace>
|
|
<Namespace>Amazon.S3.IO</Namespace>
|
|
<Namespace>Amazon.S3.Model</Namespace>
|
|
<Namespace>Amazon.S3.Model.Internal.MarshallTransformations</Namespace>
|
|
<Namespace>Amazon.S3.Transfer</Namespace>
|
|
<Namespace>Amazon.S3.Util</Namespace>
|
|
<Namespace>Amazon.Util</Namespace>
|
|
<Namespace>Amazon.Util.Internal</Namespace>
|
|
<Namespace>Amazon.Util.Internal.PlatformServices</Namespace>
|
|
<Namespace>Newtonsoft.Json</Namespace>
|
|
<Namespace>Newtonsoft.Json.Converters</Namespace>
|
|
<Namespace>Newtonsoft.Json.Linq</Namespace>
|
|
<Namespace>Newtonsoft.Json.Schema</Namespace>
|
|
<Namespace>Newtonsoft.Json.Serialization</Namespace>
|
|
<Namespace>System</Namespace>
|
|
<Namespace>System.Diagnostics</Namespace>
|
|
<Namespace>System.Diagnostics.Tracing</Namespace>
|
|
<Namespace>System.IO.Compression</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Asn1</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Asn1.Utilities</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Math</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.OpenSsl</Namespace>
|
|
<Namespace>ThirdParty.BouncyCastle.Utilities.IO.Pem</Namespace>
|
|
<Namespace>ThirdParty.Ionic.Zlib</Namespace>
|
|
<Namespace>ThirdParty.Json.LitJson</Namespace>
|
|
<Namespace>ThirdParty.MD5</Namespace>
|
|
</Query>
|
|
|
|
private string tableQuery = @"SELECT c.TABLE_SCHEMA, c.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE
|
|
, CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey
|
|
FROM INFORMATION_SCHEMA.COLUMNS AS c
|
|
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc ON tc.TABLE_SCHEMA = c.TABLE_SCHEMA AND tc.TABLE_NAME = c.TABLE_NAME
|
|
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS ccu ON ccu.TABLE_SCHEMA = tc.TABLE_SCHEMA AND ccu.TABLE_NAME = tc.TABLE_NAME AND ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND ccu.COLUMN_NAME = c.COLUMN_NAME
|
|
WHERE c.TABLE_SCHEMA in ('stratasphere')
|
|
AND (CASE c.TABLE_SCHEMA
|
|
WHEN 'stratasphere' THEN 1
|
|
ELSE
|
|
CASE WHEN c.TABLE_NAME IN ('DimCaseType', 'CaseTypeFamily', 'CaseTypeFamilyMapping', 'CaseTypeFamilyMappingAPRDRG', 'CaseTypeFamilyMappingICD10', 'CaseTypeFamilyMappingCPT', 'CaseTypeFamilyVersion')
|
|
THEN 1 ELSE 0 END END = 1)
|
|
AND c.DATA_TYPE NOT IN ('datetime','uniqueidentifier', 'timestamp')
|
|
AND NOT (c.COLUMN_NAME = 'RowID' and CAST(CASE WHEN ccu.CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS BIT) = 1)
|
|
AND tc.CONSTRAINT_TYPE = 'Primary Key'
|
|
ORDER BY c.TABLE_NAME, c.ORDINAL_POSITION";
|
|
|
|
private List<OrderByInformation> OrderByStatements;
|
|
private List<ColumnsToExclude> ColumnsToBeExcluded;
|
|
|
|
void Main()
|
|
{
|
|
OrderByStatements = new List<OrderByInformation>
|
|
{
|
|
new OrderByInformation{
|
|
TableName = "cci.InitiativeWorkflowHistory",
|
|
OrderBy = "\r\nOrder By OBJ.FromStep, OBJ.ToStep"
|
|
},
|
|
new OrderByInformation{
|
|
TableName = "cci.VariationEncounterSavingInfo",
|
|
OrderBy = "\r\nOrder By OBJ.EncounterRecordNumber, OBJ.PhysicianID"
|
|
},
|
|
new OrderByInformation{
|
|
TableName = "stratasphere.MDXScoreToCube",
|
|
OrderBy = "\r\nOrder By OBJ.OrgPin, OBJ.ScoreDimensionName, ScoreHierarchyName"
|
|
}
|
|
};
|
|
ColumnsToBeExcluded = new List<ColumnsToExclude> {
|
|
new ColumnsToExclude{
|
|
TableName = "stratasphere.MDXScoreToCube",
|
|
ColumnNames = new [] {"DateCreated", "DateLastModified"}
|
|
}
|
|
};
|
|
var conn = new Tuple<string, string>("D0011-SQL-01.sdt.local", "stratasphere");
|
|
var q = GetQueries(conn);
|
|
|
|
var connections = new ServerInstance[] {
|
|
new ServerInstance("D0011-SQL-01.sdt.local","stratasphere", q.Select(r => r.TableName).ToArray()),
|
|
new ServerInstance("E0001-SQL-11.sdt.local", "stratasphere", q.Select(r => r.TableName).ToArray() )
|
|
}.ToList();
|
|
var sql = string.Join("\r\n", q.Select(r => r.SqlSelect));
|
|
var dataLegacy = GetData(connections[0], sql);
|
|
var dataUpdate = GetData(connections[1], sql);
|
|
|
|
foreach (var dt in Enumerable.Range(0, dataLegacy.Tables.Count))
|
|
{
|
|
var legacy = dataLegacy.Tables[dt].Rows;
|
|
var update = dataUpdate.Tables[dt].Rows;
|
|
var idxCount = legacy.Count;
|
|
var compare = new List<Tuple<DataRow, DataRow>>();
|
|
foreach (var row in Enumerable.Range(0, idxCount))
|
|
{
|
|
var r = legacy[row];
|
|
if (row < update.Count)
|
|
{
|
|
var u = update[row];
|
|
var rJson = JsonConvert.SerializeObject(r.ItemArray);
|
|
var uJson = JsonConvert.SerializeObject(u.ItemArray);
|
|
if (rJson != uJson)
|
|
{
|
|
compare.Add(new Tuple<DataRow, DataRow>(r, u));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
compare.Add(new Tuple<DataRow, DataRow>(r, null));
|
|
}
|
|
}
|
|
if (compare.Any())
|
|
{
|
|
compare.Dump(dataLegacy.Tables[dt].TableName, 2);
|
|
}
|
|
else
|
|
{
|
|
"No differences found in data".Dump(dataLegacy.Tables[dt].TableName);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Define other methods and classes here
|
|
|
|
public class ServerInstance
|
|
{
|
|
public string Server { get; set; }
|
|
public string Database { get; set; }
|
|
public IEnumerable<string> TableNames { get; set; }
|
|
public ServerInstance(string server, string database, string[] tableNames)
|
|
{
|
|
Server = server;
|
|
Database = database;
|
|
TableNames = tableNames;
|
|
}
|
|
}
|
|
|
|
public class OrderByInformation
|
|
{
|
|
public string TableName { get; set; }
|
|
public string OrderBy { get; set; }
|
|
}
|
|
|
|
public class ColumnsToExclude
|
|
{
|
|
public string TableName { get; set; }
|
|
public IEnumerable<string> ColumnNames { get; set; }
|
|
}
|
|
|
|
public List<SqlInformation> GetQueries(Tuple<string, string> connection)
|
|
{
|
|
var server = connection.Item1;
|
|
var database = connection.Item2;
|
|
var sql = tableQuery;
|
|
var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;";
|
|
using (var conn = new SqlConnection(connStr))
|
|
{
|
|
var dataset = new DataTable();
|
|
var adapter = new SqlDataAdapter(sql, conn);
|
|
adapter.Fill(dataset);
|
|
var items = dataset.AsEnumerable().Select(r => r).ToList().ConvertAll(r => r.ItemArray)
|
|
.Select(r => new InformationSchema { schema = (string)r[0], table = (string)r[1], column = (string)r[2], datatype = (string)r[3], isPrimaryKey = (bool)r[4] })
|
|
.Where(r => !ColumnsToBeExcluded.SingleOrDefault(ctbe => ctbe.TableName == r.schemaTable)?.ColumnNames.Contains(r.column) ?? true)
|
|
.GroupBy(r => new { r.schema, r.table }, (t, c) =>
|
|
new SqlInformation
|
|
{
|
|
TableName = $"{t.schema}.{t.table}",
|
|
SqlSelect = "Select\r\n" + c.Aggregate("", (x, y) => $"{x}, obj.{y.column}\r\n").Substring(1) + $" FROM {t.schema}.{t.table} OBJ"
|
|
+ OrderByStatements.SingleOrDefault(obs => obs.TableName.Equals($"{t.schema}.{t.table}", StringComparison.CurrentCultureIgnoreCase))?.OrderBy ?? ""
|
|
+ ";"
|
|
})
|
|
.ToList();
|
|
return items;
|
|
}
|
|
}
|
|
|
|
public class SqlInformation
|
|
{
|
|
public string TableName { get; set; }
|
|
public string SqlSelect { get; set; }
|
|
}
|
|
|
|
public class InformationSchema
|
|
{
|
|
public string schema { get; set; }
|
|
public string table { get; set; }
|
|
public string column { get; set; }
|
|
public string datatype { get; set; }
|
|
public bool isPrimaryKey { get; set; }
|
|
public string schemaTable => $"{schema}.{table}";
|
|
}
|
|
|
|
public DataSet GetData(ServerInstance serverInstance, string sql)
|
|
{
|
|
var server = serverInstance.Server;
|
|
var database = serverInstance.Database;
|
|
var connStr = $"data source={server};initial catalog='{database}';persist security info=True;Integrated Security=SSPI;";
|
|
using (var conn = new SqlConnection(connStr))
|
|
{
|
|
var dataset = new DataSet();
|
|
var adapter = new SqlDataAdapter(sql, conn);
|
|
adapter.Fill(dataset);
|
|
var tableNames = serverInstance.TableNames;
|
|
var idx = 0;
|
|
foreach (var tableName in tableNames)
|
|
{
|
|
dataset.Tables[idx].TableName = tableName;
|
|
idx += 1;
|
|
}
|
|
return dataset;
|
|
}
|
|
} |