c# - 如何从 C# SQL Server 中的特定架构中删除所有表?
问题描述
我正在进行数据库迁移,我需要删除特定模式中的所有表,然后运行另一个脚本以从另一个数据库重新创建它们。
我在尝试以正确的顺序删除特定表时遇到了问题。
是否有一个 SQL 查询可以按正确的顺序对表进行排序,以便可以正确删除它们?
这是到目前为止我正在尝试的代码,但表格的顺序不正确:
private void CreateDropStatementsAndRun(string schema)
{
string sql = string.Format(@"SELECT table_name
FROM information_schema.tables
WHERE table_schema = '{0}';", schema);
var connectionString = ConfigurationManager.ConnectionStrings["TARGET_DefaultConnection"];
StringBuilder sb = new StringBuilder();
var listOfTables = new List<string>();
using (SqlConnection conn = new SqlConnection(connectionString.ConnectionString))
{
conn.Open();
using (var command = new SqlCommand(sql, conn))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
listOfTables.Add(reader.GetString(0));
}
}
}
foreach (var item in listOfTables)
{
sb.AppendFormat("alter table {0}.{1} nocheck constraint all;", schema, item).AppendLine();
sb.AppendFormat("DROP TABLE IF EXISTS {0}.{1};", schema, item).AppendLine();
}
using (var cmd = new SqlCommand(sb.ToString(), conn))
{
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
}
解决方案
这是我的答案:
专注于ORDER BY dependency_level desc
然后where schema_Name = '{0}'
这是我找到答案的地方:如何按依赖顺序列出表(基于外键)?
private void CreateDropStatementsAndRun(string schema)
{
string sql = string.Format(@"WITH cte (lvl, object_id, name, schema_Name) AS
(SELECT 1, object_id, sys.tables.name, sys.schemas.name as schema_Name
FROM sys.tables Inner Join sys.schemas on sys.tables.schema_id = sys.schemas.schema_id
WHERE type_desc = 'USER_TABLE'
AND is_ms_shipped = 0
UNION ALL SELECT cte.lvl + 1, t.object_id, t.name, S.name as schema_Name
FROM cte
JOIN sys.tables AS t ON EXISTS
(SELECT NULL FROM sys.foreign_keys AS fk
WHERE fk.parent_object_id = t.object_id
AND fk.referenced_object_id = cte.object_id )
JOIN sys.schemas as S on t.schema_id = S.schema_id
AND t.object_id <> cte.object_id
AND cte.lvl < 30
WHERE t.type_desc = 'USER_TABLE'
AND t.is_ms_shipped = 0 )
SELECT schema_Name, name, MAX (lvl) AS dependency_level
FROM cte
where schema_Name = '{0}'
GROUP BY schema_Name, name
ORDER BY dependency_level desc,schema_Name, name;", schema);
var connectionString = ConfigurationManager.ConnectionStrings["TARGET_DefaultConnection"];
StringBuilder sb = new StringBuilder();
var listOfTables = new List<string>();
using (SqlConnection conn = new SqlConnection(connectionString.ConnectionString))
{
conn.Open();
using (var command = new SqlCommand(sql, conn))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
listOfTables.Add(reader.GetString(1));
}
}
}
if (listOfTables.Count > 0)
{
foreach (var item in listOfTables)
{
sb.AppendFormat("DROP TABLE IF EXISTS {0}.{1};", schema, item).AppendLine();
}
using (var cmd = new SqlCommand(sb.ToString(), conn))
{
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
}
}
推荐阅读
- android - ScrollView 在片段中不起作用
- php - 最后一个值没有存储在codeigniter会话中的数组中
- oracle - 如何将 oracle 日期格式转换为 IST 格式?
- c# - 在 Visual Studio 代码中构建现有代码
- r - 与上一时期相比,显示增加/减少值的变异列
- python - 使用 apt_pkg 以编程方式安装 debian 软件包时出错
- json - 如何将原始字典转换为 JSON 字符串?
- javascript - 如何使用 javascript 和 jquery 在 html 中动态创建 div 卡?
- elixir - 如何查看一个文件是从另一个文件导入还是作为入口点运行?
- networking - 当客户端尝试连接到接入点并且主路由器中有可用位置时重定向客户端