Skip to content

Instantly share code, notes, and snippets.

@joebuschmann
Created December 2, 2014 03:00
Show Gist options
  • Select an option

  • Save joebuschmann/7c6f98c133aa15bd6fb8 to your computer and use it in GitHub Desktop.

Select an option

Save joebuschmann/7c6f98c133aa15bd6fb8 to your computer and use it in GitHub Desktop.
C# program to generate SQL delete statements in FK order
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Text;
namespace TruncateData
{
public class Program
{
private static SqlConnection _connection;
private static StringBuilder _buffer;
private const string spFKeysTemplate = "exec sp_fkeys '{0}'";
private const string deleteTemplate = "delete [{ftable}] from [{ftable}]";
private const string joinTemplate = "\tjoin [{ptable}] on [{ptable}].[{pcolumn}] = [{ftable}].[{fcolumn}]";
static void Main(string[] args)
{
string connectionString = args[0];
string targetTable = args[1];
string where = args[2];
string outputfile = args[3];
bool replaceFile = true;
try
{
if (args.Length > 4)
replaceFile = GetReplaceFile(args[4]);
_buffer = new StringBuilder();
_connection = new SqlConnection(connectionString);
using (_connection)
{
WriteStatementsForTargetTable(targetTable, where);
_buffer.AppendLine(string.Format("delete from [{0}] {1}", targetTable, where));
_buffer.AppendLine();
_buffer.AppendLine("go");
_buffer.AppendLine();
}
if (replaceFile)
File.WriteAllText(outputfile, _buffer.ToString());
else
File.AppendAllText(outputfile, _buffer.ToString());
}
catch (Exception e)
{
Console.WriteLine("The programe failed with:\n\n{0}", e.Message);
}
}
private static bool GetReplaceFile(string replaceFileArg)
{
if (replaceFileArg == "1")
replaceFileArg = "true";
else if (replaceFileArg == "0")
replaceFileArg = "false";
return Convert.ToBoolean(replaceFileArg);
}
private static void WriteStatementsForTargetTable(string targetTable, string where, string parentJoin = null)
{
var foreignKeyTables = GetForeignKeyInfo(targetTable, _connection);
foreach (var foreignKeyTable in foreignKeyTables)
{
string join =
joinTemplate.Replace("{ptable}", foreignKeyTable.PTable)
.Replace("{pcolumn}", foreignKeyTable.PColumn)
.Replace("{ftable}", foreignKeyTable.FTable)
.Replace("{fcolumn}", foreignKeyTable.FColumn);
if (parentJoin != null)
join = join + Environment.NewLine + parentJoin;
// Write out child deletes before this one to prevent FK violations.
WriteStatementsForTargetTable(foreignKeyTable.FTable, where, join);
string delete = deleteTemplate.Replace("{ftable}", foreignKeyTable.FTable);
_buffer.AppendLine(delete);
_buffer.AppendLine(join);
if (!string.IsNullOrEmpty(where))
_buffer.AppendLine(where);
_buffer.AppendLine();
_buffer.AppendLine("go");
_buffer.AppendLine();
}
}
private static List<FkInfo> GetForeignKeyInfo(string targetTable, SqlConnection connection)
{
connection.Open();
var foreignKeyTables = new List<FkInfo>();
var command = new SqlCommand(string.Format(spFKeysTemplate, targetTable), connection);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
foreignKeyTables.Add(new FkInfo()
{
PTable = reader["PKTABLE_NAME"].ToString(),
PColumn = reader["PKCOLUMN_NAME"].ToString(),
FTable = reader["FKTABLE_NAME"].ToString(),
FColumn = reader["FKCOLUMN_NAME"].ToString()
});
}
}
reader.Close();
connection.Close();
foreignKeyTables.RemoveAll(fkInfo => fkInfo.FTable == fkInfo.PTable);
return foreignKeyTables;
}
private class FkInfo
{
public string PTable { get; set; }
public string PColumn { get; set; }
public string FTable { get; set; }
public string FColumn { get; set; }
}
}
}
@Bafan

Bafan commented Jul 31, 2017

Copy link
Copy Markdown

Useful
Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment