我有一个SQL Server数据库,其中包含一些表,每个表都有一个主键和一些外键约束。
我想将数据库表备份到.sql
文件中,以便稍后可以恢复数据库。
我尝试了几种ScriptOptions
组合,但并没有得到想要的结果。
问题是表的CREATE
语句未按其依存顺序显示。如果表A具有表B的外键,则在我的脚本中首先列出表A的CREATE
语句。这样我就无法还原数据库。
我尝试使用ScriptOptions.WithDependencies = true
。但是随后,表B的CREATE
语句被添加了两次,我不希望这样做。
我使用的方法是先将模式仅转储,然后将所有约束转储到同一SQL文件中。
这是我的示例C#代码段:
ServerConnection sc = new ServerConnection(args[0], args[1], args[2]);
Server myServer = new Server(sc);
myServer.SetDefaultInitFields(typeof(StoredProcedure), "IsSystemObject");
myServer.SetDefaultInitFields(typeof(UserDefinedFunction), "IsSystemObject");
Database db = default(Database);
db = myServer.Databases[args[3]];
StringBuilder sb = new StringBuilder();
StringBuilder sbConstraints = new StringBuilder();
Scripter dropScrp = default(Scripter);
dropScrp = new Scripter(myServer);
dropScrp.Options.IncludeIfNotExists = true;
dropScrp.Options.ScriptSchema = true;
dropScrp.Options.ScriptDrops = true;
Scripter createScrp = default(Scripter);
createScrp = new Scripter(myServer);
createScrp.Options.IncludeIfNotExists = true;
createScrp.Options.ScriptSchema = true;
Scripter constratintScrp = default(Scripter);
constratintScrp = new Scripter(myServer);
constratintScrp.Options.DriAllKeys = true;
foreach (Table tb in db.Tables)
{
if (tb.IsSystemObject == false)
{
foreach (string s in dropScrp.EnumScript(new Urn[] { tb.Urn }))
{
sb.AppendLine(s);
}
foreach (string s in createScrp.EnumScript(new Urn[] { tb.Urn }))
{
sb.AppendLine(s);
}
foreach (string s in constratintScrp.EnumScript(new Urn[] { tb.Urn }))
{
sbConstraints.AppendLine(s);
}
sb.AppendLine("");
}
}
sb.AppendLine(sbConstraints.ToString());
File.WriteAllText(args[4], sb.ToString());
答案 0 :(得分:0)
我这样解决了我的问题:
StringBuilder sb = new StringBuilder();
StringBuilder sbConstraints = new StringBuilder();
StringBuilder sbData = new StringBuilder();
Scripter dropScrp = default(Scripter);
dropScrp = new Scripter(myServer);
dropScrp.Options.IncludeIfNotExists = true;
dropScrp.Options.ScriptSchema = true;
dropScrp.Options.ScriptDrops = true;
Scripter createScrp = default(Scripter);
createScrp = new Scripter(myServer);
createScrp.Options.ScriptSchema = true;
createScrp.Options.NoCommandTerminator = false;
createScrp.Options.ScriptBatchTerminator = true;
createScrp.Options.DriPrimaryKey = true;
createScrp.Options.IncludeIfNotExists = true;
Scripter constratintScrp = default(Scripter);
constratintScrp = new Scripter(myServer);
constratintScrp.Options.Default = false;
constratintScrp.Options.DriUniqueKeys = true;
constratintScrp.Options.DriForeignKeys = true;
constratintScrp.Options.DriPrimaryKey = false;
Scripter dataScrp = default(Scripter);
dataScrp = new Scripter(myServer);
dataScrp.Options.ScriptData = true;
dataScrp.Options.ScriptSchema = false;
foreach (Table tb in db.Tables)
{
if (tb.IsSystemObject == false)
{
foreach (string s in dropScrp.EnumScript(new Urn[] { tb.Urn }))
{
sb.AppendLine(s);
}
foreach (string s in createScrp.EnumScript(new Urn[] { tb.Urn }))
{
sb.AppendLine(s);
}
foreach (string s in constratintScrp.EnumScript(new Urn[] { tb.Urn }))
{
sbConstraints.AppendLine(s);
}
foreach (string s in dataScrp.EnumScript(new Urn[] { tb.Urn }))
{
sbData.AppendLine(s);
}
sb.AppendLine("");
sbConstraints.AppendLine("");
sbData.AppendLine("");
}
}
sb.AppendLine(sbData.ToString());
sb.AppendLine(sbConstraints.ToString());
这将按以下顺序生成sql脚本。
为每个表创建约束语句(不是主键约束)。
在应用约束之前,我必须首先将数据插入表中,因为我无法以任何方式将数据按其依赖顺序插入。这也是我最初的问题。因此,我先插入数据,然后在表上应用约束。