Skip to content

Instantly share code, notes, and snippets.

@MarkPflug
Created January 19, 2024 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MarkPflug/af84393127141e04ef0aa22ff156cda8 to your computer and use it in GitHub Desktop.
Save MarkPflug/af84393127141e04ef0aa22ff156cda8 to your computer and use it in GitHub Desktop.
SQL TZ Convert
using System.Data.SqlClient;
internal class Program
{
static void Main(string[] args)
{
var dbStr = args[0];
var srcTz = args[1];
var dstTz = args[2];
string srv, db;
if (dbStr.Contains(':'))
{
srv = dbStr.Substring(0, dbStr.IndexOf(':'));
db = dbStr.Substring(dbStr.IndexOf(':')+1);
}
else
{
srv = ".";
db = dbStr;
}
var csb = new SqlConnectionStringBuilder()
{
DataSource = srv,
InitialCatalog = db,
IntegratedSecurity = true,
TrustServerCertificate = true,
};
var conn = new SqlConnection(csb.ConnectionString);
conn.Open();
DatabaseTimeZoneUpdate.UpdateTimeZone(conn, srcTz, dstTz);
}
}
// a process to update all datetime values to be in a given timezone
public static class DatabaseTimeZoneUpdate
{
public static void ValidateTimeZone(SqlConnection conn, string tzId)
{
using var cmd = conn.CreateCommand();
cmd.CommandText = "select count(1) from sys.time_zone_info where name = @id";
cmd.Parameters.AddWithValue("id", tzId);
if (cmd.ExecuteScalar() is not 1)
{
throw new ArgumentOutOfRangeException(nameof(tzId), $"Timezone {tzId} is not known by SqlServer");
}
}
public static void UpdateTimeZone(SqlConnection conn, string srcTzId, string dstTzId)
{
// Validate that the timezone names are correct.
ValidateTimeZone(conn, srcTzId);
ValidateTimeZone(conn, dstTzId);
var cmd = conn.CreateCommand();
// get all the datetime and datetime2 columns in the database.
cmd.CommandText =
"""
select
      s.name as schemaName,
      ta.name as tableName,
      c.name as columnName,
      t.name as typeName
from sys.columns c
join sys.tables ta
      on c.object_id = ta.object_id
join sys.schemas s
      on ta.schema_id = s.schema_id
join sys.types t
      on c.system_type_id = t.system_type_id
where
      t.name in ('datetime', 'datetime2')
order by
      s.name, ta.name, c.name
""";
var sw = new StringWriter();
using (var reader = cmd.ExecuteReader())
{
sw.WriteLine($"declare @SrcTzId varchar(128) = '{srcTzId}'");
sw.WriteLine($"declare @DstTzId varchar(128) = '{dstTzId}'");
string? table = null;
while (reader.Read())
{
var schemaName = reader.GetString(0);
var tableName = reader.GetString(1);
var columnName = reader.GetString(2);
var typeName = reader.GetString(3);
if (tableName != table)
{
if (table != null)
{
sw.WriteLine(";");
}
sw.WriteLine($"update [{schemaName}].[{tableName}] set ");
table = tableName;
}
else
{
sw.Write(",");
}
sw.WriteLine($"{columnName} = {columnName} at time zone @SrcTzId at time zone @DstTzId");
}
}
cmd.CommandText = sw.ToString();
// this command can take a while.
cmd.CommandTimeout = (int)TimeSpan.FromHours(1).TotalSeconds;
cmd.ExecuteNonQuery();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment