-->

不能得到EnumScript()来生成约束(can't get EnumScript() t

2019-10-18 16:39发布

我试图让编程我可以手动从SSMS使用任务获得>生成脚本

下面的代码工作正常,但它不会产生任何约束。 我没有得到任何ALTER TABLE [foo] ADD CONSTRAINT ... ON DELETE CASCADE等等等等,我已经尝试了很多的组合, Dri的选择和在不同的数据库,以及。 我难倒。

感谢您的见解!

        Scripter scrp = new Scripter(srv)
        {
            Options =
            {
                ScriptDrops = false,
                WithDependencies = false,
                Indexes = true,
                Triggers = false,
                Default = true,
                DriAll = true,
                //ScriptData = true,
                ScriptSchema = true,
            }
        };

        var urns = new List<Urn>();

        foreach (Table tb in db.Tables)
        {
            if (tb.IsSystemObject == false)
            {
                urns.Add(tb.Urn);
            }
        }

        var inserts = scrp.EnumScript(urns.ToArray());
        File.WriteAllLines(path, inserts);

Answer 1:

好了,我发现了一个解决方案,这是使用Script的每个对象的方法,以产生架构和EnumScript方法(带scriptSchema=false ),以产生插入件为表的内容。

        foreach (Table tb in db.Tables)
        {
            if (tb.IsSystemObject == false)
            {
                foreach (var s in tb.Script(schemaOptions))
                    strings.Add(s);

                if (scriptData)
                {
                    foreach (var i in tb.EnumScript(insertOptions))
                        strings.Add(i);
                }
            }
        }

我承认这个解决方案感觉有点空洞,因为我从来没有发现,为什么原来的方法没有奏效。 这是没有诊断修复,但修复仍然。

至于为什么我首先写这个东西,我的数据库是一个共享的服务器上,并没有任何办法得到一个自动备份,我可以离线或其他地方使用。 所以这是我的备用方案。

上述解决方案遵循微软此处给出的代码示例: 脚本 。 这种方法的问题是表中没有特定的顺序照本宣科,而是需要在它们的依赖顺序为了要定义的约束和对要插入的行。 不能引用一个表的外键尚不存在。

最好的解决办法我至今是使用DependencyWalker.DiscoverDependencies()获得的依赖关系树, DependencyWalker.WalkDependencies()得到一个线性表,并遍历该列表,如下所示:

        var urns = new List<Urn>();
        Scripter schemaScripter = new Scripter(srv) { Options = schemaOptions };
        Scripter insertScripter = new Scripter(srv) { Options = insertOptions };
        var dw = new DependencyWalker(srv);

        foreach (Table t in db.Tables)
            if (t.IsSystemObject == false)
                urns.Add(t.Urn);
        DependencyTree dTree = dw.DiscoverDependencies(urns.ToArray(), true);
        DependencyCollection dColl = dw.WalkDependencies(dTree);

        foreach (var d in dColl)
        {
            foreach (var s in schemaScripter.Script(new Urn[] { d.Urn }))
                strings.Add(s);
            strings.Add("GO");
            if (scriptData)
            {
                int n = 0;
                foreach (var i in insertScripter.EnumScript(new Urn[] {d.Urn}))
                {
                    strings.Add(i);
                    if ((++n) % 100 == 0)
                        strings.Add("GO");
                }
            }
        }
        ...
        File.WriteAllLines(path, strings);

添加一个“GO”,每隔一段时间保持批量小,所以SSMS没有用完的内存。

为了完成这个例子,数据库中获取这样的脚本:

        foreach (var s in db.Script(new ScriptingOptions { ScriptSchema = true }))
            strings.Add(s);
        strings.Add("GO");
        strings.Add("use " + dbName);
        strings.Add("GO");

用户,视图,存储过程因此脚本:

        foreach (User u in db.Users)
        {
            if (u.IsSystemObject == false)
            {
                foreach (var s in u.Script(new ScriptingOptions { ScriptSchema = true }))
                    strings.Add(s);
            }
        }

由此代码生成的文件可以用于重新创建数据库。 我有它设置上的旧笔记本电脑来拉我的每一个小时的在线数据库的快照。 穷人的日志传送/备份/镜像。



文章来源: can't get EnumScript() to generate constraints