如何使用SMO生成T-SQL脚本

时间:2018-07-06 12:39:56

标签: sql-server database backup smo

我有一个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());

1 个答案:

答案 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脚本。

  1. 每张桌子
    1. 带有是否存在检查的丢弃语句。
    2. 使用不存在的检查创建语句。这还将包括主键约束。
  2. 为每个表插入数据语句。
  3. 为每个表创建约束语句(不是主键约束)。

    在应用约束之前,我必须首先将数据插入表中,因为我无法以任何方式将数据按其依赖顺序插入。这也是我最初的问题。因此,我先插入数据,然后在表上应用约束。