Avatar billede keepy Seniormester
13. juli 2018 - 14:08 Der er 2 kommentarer og
1 løsning

Migrerer fra SQL server til SQL Compact

Hej
Hvordan får jeg konverteret min sql database til en sql compact .sdf ?
Der findes et tool til dette, men jeg har brug for at kunne lave et script der gør arbejdet, så jeg kan udføre opgaven fra min egen applikation(C# program).
Håber nogle kan hjælpe mig på rette vej eller måske en da et lille eksempel.

På forhånd tak.
Avatar billede arne_v Ekspert
16. juli 2018 - 05:13 #1
Det er ikke helt simpelt.

Men her er et foerste udkast:


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Text;

namespace E
{
    public class DbDump
    {
        public delegate bool SelectDatabase(string db);
        public delegate bool SelectTable(string db, string tbl);
        public delegate bool SelectField(string db, string tbl,string fld);
        public static void DumpTableStructure(IDbConnection con, string db, string catsuf, string tbl, StreamWriter sw, SelectField selfld)
        {
            sw.WriteLine("CREATE TABLE {0} (", tbl);
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE,IS_NULLABLE,ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_" + catsuf + "='" + db + "' AND TABLE_NAME='" + tbl + "'";
            IDataReader rdr = cmd.ExecuteReader();
            string pk = "?";
            while(rdr.Read())
            {
                string fld = (string)rdr[0];
                string typ = (string)rdr[1];
                bool nl = (string)rdr[5] == "YES";
                if(selfld(db, tbl, fld))
                {
                    string add = "";
                    switch(typ)
                    {
                        case "int":
                            // nothing
                            break;
                        case "varchar":
                        case "char":
                            add = "(" + rdr[2] + ")";
                            break;
                        case "decimal":
                        case "numeric":
                            add = "(" + rdr[3] + "," + rdr[4] + ")";
                            break;
                        default:
                            throw new ApplicationException("Unsupported data type: " + typ);
                    }
                    sw.WriteLine("    {0} {1}{2} {3},", fld, typ, add, nl ? "NULL" : "NOT NULL");
                }
                if(rdr[6].ToString() == "1") pk = fld; // **** CRAZY GUESS ****
            }
            rdr.Close();
            sw.WriteLine("    PRIMARY KEY({0})", pk);
            sw.WriteLine(");");
        }
        public static void DumpTableData(IDbConnection con, string db, string tbl, StreamWriter sw, SelectField selfld)
        {
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "USE " + db;
            cmd.ExecuteNonQuery();
            cmd.CommandText = "SELECT * FROM " + tbl;
            List<string> alltbl = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string flds = "";
                string vals = "";
                for(int i = 0; i < rdr.FieldCount; i++)
                {
                    if(selfld(db, tbl, rdr.GetName(i)))
                    {
                        if(i > 0)
                        {
                            flds += ",";
                            vals += ",";
                        }
                        flds += rdr.GetName(i);
                        object o = rdr.GetValue(i);
                        if(o is DBNull)
                        {
                            vals += "NULL";
                        }
                        else if(o is int
                                || o is long
                                || o is float
                                || o is bool
                                || o is double
                                || o is decimal)
                        {
                            vals += o.ToString();
                        }
                        else if(o is string)
                        {
                            vals += ("'" + o.ToString().Replace("'", "''") + "'");
                        }
                        else
                        {
                            throw new ApplicationException("Unsupported data type: " + o.GetType().FullName);
                        }
                    }
                }
                sw.WriteLine("INSERT INTO {0}({1}) VALUES({2});", tbl, flds, vals);
            }
            rdr.Close();
        }
        public static void DumpTable(IDbConnection con, string db, string catsuf, string tbl, StreamWriter sw, SelectField selfld)
        {
            DumpTableStructure(con, db, catsuf, tbl, sw, selfld);
            DumpTableData(con, db, tbl, sw, selfld);
        }
        public static void DumpDatabase(IDbConnection con, string db, string catsuf, StreamWriter sw, SelectTable seltbl, SelectField selfld)
        {
            sw.WriteLine("USE {0};", db);
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_" + catsuf + "='" + db + "' AND TABLE_TYPE='BASE TABLE'";
            List<string> alltbl = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string tbl = (string)rdr[0];
                if(seltbl(db, tbl))
                {
                    alltbl.Add(tbl);
                }
            }
            rdr.Close();
            foreach(string tbl in alltbl)
            {
                DumpTable(con, db, catsuf, tbl, sw, selfld);
            }
        }
        public static void DumpServer(IDbConnection con, string catsuf, StreamWriter sw, SelectDatabase seldb, SelectTable seltbl, SelectField selfld)
        {
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT DISTINCT TABLE_" + catsuf + " FROM INFORMATION_SCHEMA.TABLES";
            List<string> alldb = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string db = (string)rdr[0];
                if(!db.StartsWith("sys") && !db.Equals("mysql") && seldb(db))
                {
                    alldb.Add(db);
                }
            }
            rdr.Close();
            foreach(string db in alldb)
            {
                DumpDatabase(con, db, catsuf, sw, seltbl, selfld);
            }
        }
        public static void Dump(string provider, string constr, string catsuf, string fnm, SelectDatabase seldb, SelectTable seltbl, SelectField selfld)
        {
            DbProviderFactory dbf = DbProviderFactories.GetFactory(provider);
            using(IDbConnection con = dbf.CreateConnection())
            {
                con.ConnectionString = constr;
                con.Open();
                using(StreamWriter sw = new StreamWriter(fnm, false, Encoding.UTF8))
                {
                    DumpServer(con, catsuf, sw, seldb, seltbl, selfld);
                }
            }
        }
        public static void Dump(string provider, string constr, string catsuf, string fnm)
        {
            Dump(provider, constr, catsuf, fnm, (db) => true, (db, tbl) => true, (db, tbl, fld) => true);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DbDump.Dump("System.Data.SqlClient", @"Server=ARNEPC4\SQLEXPRESS;Integrated Security=true;Database=Test", "CATALOG", @"C:\work\ss.txt");
            DbDump.Dump("MySql.Data.MySqlClient", "Data Source=localhost;Database=Test;User Id=root;Password=", "SCHEMA", @"C:\work\ms.txt");
            DbDump.Dump("System.Data.SqlClient", @"Server=ARNEPC4\SQLEXPRESS;Integrated Security=true;Database=Test", "CATALOG", @"C:\work\ss2.txt", (db) => db == "test", (db, tbl) => true, (db, tbl, fld) => (tbl != "T1" || fld != "F2"));
        }
    }
}
Avatar billede keepy Seniormester
17. juli 2018 - 09:04 #2
Tak Arne det vil jeg kigge lidt nærmere på
Avatar billede arne_v Ekspert
17. juli 2018 - 20:05 #3

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Text;

namespace E
{
    public class DbDump
    {
        public delegate bool SelectDatabase(string db);
        public delegate bool SelectTable(string db, string tbl);
        public delegate bool SelectField(string db, string tbl,string fld);
        public static void DumpTableStructure(IDbConnection con, string db, string catsuf, string tbl, StreamWriter sw, SelectField selfld)
        {
            sw.WriteLine("CREATE TABLE {0} (", tbl);
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT c.COLUMN_NAME,c.DATA_TYPE,c.CHARACTER_MAXIMUM_LENGTH,c.NUMERIC_PRECISION,c.NUMERIC_SCALE,c.IS_NULLABLE,tc.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.COLUMNS c LEFT JOIN (INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON tc.TABLE_" + catsuf + " = kcu.TABLE_" + catsuf + " AND tc.TABLE_NAME = kcu.TABLE_NAME AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY') ON c.TABLE_" + catsuf + " = tc.TABLE_" + catsuf + " AND c.TABLE_NAME = tc.TABLE_NAME AND c.COLUMN_NAME = kcu.COLUMN_NAME WHERE c.TABLE_" + catsuf + "='" + db + "' AND c.TABLE_NAME='" + tbl + "'";
            IDataReader rdr = cmd.ExecuteReader();
            List<string> pk = new List<string>();
            while(rdr.Read())
            {
                string fld = (string)rdr[0];
                string typ = (string)rdr[1];
                string maxlen = rdr[2].ToString();
                string prec = rdr[3].ToString();
                string scale = rdr[4].ToString();
                bool nl = (string)rdr[5] == "YES";
                bool ispk = !(rdr[6] is DBNull);
                if(selfld(db, tbl, fld))
                {
                    string add = "";
                    switch(typ)
                    {
                        case "int":
                            // nothing
                            break;
                        case "varchar":
                        case "char":
                            add = "(" + maxlen + ")";
                            break;
                        case "decimal":
                        case "numeric":
                            add = "(" + prec + "," + scale + ")";
                            break;
                        default:
                            throw new ApplicationException("Unsupported data type: " + typ);
                    }
                    sw.WriteLine("    {0} {1}{2} {3},", fld, typ, add, nl ? "NULL" : "NOT NULL");
                }
                if(ispk)
                {
                    pk.Add(fld);
                }
            }
            rdr.Close();
            sw.WriteLine("    PRIMARY KEY({0})", pk.Count > 0 ? pk.Aggregate((tot,nxt) => tot + "," + nxt) : "?");
            sw.WriteLine(");");
        }
        public static void DumpTableData(IDbConnection con, string db, string tbl, StreamWriter sw, SelectField selfld)
        {
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "USE " + db;
            cmd.ExecuteNonQuery();
            cmd.CommandText = "SELECT * FROM " + tbl;
            List<string> alltbl = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string flds = "";
                string vals = "";
                for(int i = 0; i < rdr.FieldCount; i++)
                {
                    if(selfld(db, tbl, rdr.GetName(i)))
                    {
                        if(i > 0)
                        {
                            flds += ",";
                            vals += ",";
                        }
                        flds += rdr.GetName(i);
                        object o = rdr.GetValue(i);
                        if(o is DBNull)
                        {
                            vals += "NULL";
                        }
                        else if(o is int
                                || o is long
                                || o is float
                                || o is bool
                                || o is double
                                || o is decimal)
                        {
                            vals += o.ToString();
                        }
                        else if(o is string)
                        {
                            vals += ("'" + o.ToString().Replace("'", "''") + "'");
                        }
                        else
                        {
                            throw new ApplicationException("Unsupported data type: " + o.GetType().FullName);
                        }
                    }
                }
                sw.WriteLine("INSERT INTO {0}({1}) VALUES({2});", tbl, flds, vals);
            }
            rdr.Close();
        }
        public static void DumpTable(IDbConnection con, string db, string catsuf, string tbl, StreamWriter sw, SelectField selfld)
        {
            DumpTableStructure(con, db, catsuf, tbl, sw, selfld);
            DumpTableData(con, db, tbl, sw, selfld);
        }
        public static void DumpDatabase(IDbConnection con, string db, string catsuf, StreamWriter sw, SelectTable seltbl, SelectField selfld)
        {
            sw.WriteLine("USE {0};", db);
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_" + catsuf + "='" + db + "' AND TABLE_TYPE='BASE TABLE'";
            List<string> alltbl = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string tbl = (string)rdr[0];
                if(seltbl(db, tbl))
                {
                    alltbl.Add(tbl);
                }
            }
            rdr.Close();
            foreach(string tbl in alltbl)
            {
                DumpTable(con, db, catsuf, tbl, sw, selfld);
            }
        }
        public static void DumpServer(IDbConnection con, string catsuf, StreamWriter sw, SelectDatabase seldb, SelectTable seltbl, SelectField selfld)
        {
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT DISTINCT TABLE_" + catsuf + " FROM INFORMATION_SCHEMA.TABLES";
            List<string> alldb = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                string db = (string)rdr[0];
                if(!db.StartsWith("sys") && !db.Equals("mysql") && seldb(db))
                {
                    alldb.Add(db);
                }
            }
            rdr.Close();
            foreach(string db in alldb)
            {
                DumpDatabase(con, db, catsuf, sw, seltbl, selfld);
            }
        }
        public static void Dump(string provider, string constr, string catsuf, string fnm, SelectDatabase seldb, SelectTable seltbl, SelectField selfld)
        {
            DbProviderFactory dbf = DbProviderFactories.GetFactory(provider);
            using(IDbConnection con = dbf.CreateConnection())
            {
                con.ConnectionString = constr;
                con.Open();
                using(StreamWriter sw = new StreamWriter(fnm, false, Encoding.UTF8))
                {
                    DumpServer(con, catsuf, sw, seldb, seltbl, selfld);
                }
            }
        }
        public static void Dump(string provider, string constr, string catsuf, string fnm)
        {
            Dump(provider, constr, catsuf, fnm, (db) => true, (db, tbl) => true, (db, tbl, fld) => true);
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DbDump.Dump("System.Data.SqlClient", @"Server=ARNEPC4\SQLEXPRESS;Integrated Security=true;Database=Test", "CATALOG", @"C:\work\ss.txt");
            DbDump.Dump("MySql.Data.MySqlClient", "Data Source=localhost;Database=Test;User Id=root;Password=", "SCHEMA", @"C:\work\ms.txt");
            DbDump.Dump("System.Data.SqlClient", @"Server=ARNEPC4\SQLEXPRESS;Integrated Security=true;Database=Test", "CATALOG", @"C:\work\ss2.txt", (db) => db == "test", (db, tbl) => true, (db, tbl, fld) => (tbl != "T1" || fld != "F2"));
        }
    }
}


er bedre.

I.s.f.at antage at foerste felt er PK, saa finder den faktisk PK.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester