1

[タスク] > [スクリプトの生成] を使用して、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);
4

1 に答える 1

1

さて、解決策を見つけました。Script各オブジェクトのメソッドを使用してスキーマを生成し、EnumScriptメソッド ( with 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);
                }
            }
        }

元の方法が機能しなかった理由がわからなかったので、この解決策は少し空虚に感じられることを告白します。診断なしの修理ですが、それでも修理です。

そもそもなぜこのようなことを書いたのかというと、私のデータベースは共有サーバー上にあり、オフラインや他の場所で使用できる自動バックアップを取得する方法がありません。これが私のバックアップスキームです。

上記のソリューションは、Microsoft が提供するコード例に従います: Scripting . このアプローチの問題は、テーブルが特定の順序でスクリプト化されていないことですが、制約を定義して行を挿入するには、依存関係の順序である必要があります。まだ存在しないテーブルの外部キーを参照することはできません。

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);
            }
        }

このコードによって生成されたファイルを使用して、データベースを再作成できます。古いラップトップにセットアップして、オンライン データベースのスナップショットを 1 時間ごとに取得しています。貧乏人のログ配布/バックアップ/ミラーリング。

于 2013-09-28T18:26:42.993 に答える