Avatar billede angelenglen Nybegynder
19. juli 2011 - 15:39 Der er 13 kommentarer og
1 løsning

Kopier tabeller fra én database til en anden

Jeg har to databaser, en "online" database, og en "lokal" database.

Begge er MS SQL-2005 databaser.

Jeg har brug for at kunne kopiere en række tabeller fra den ene server til den anden, incl. data.

Alle tabeller har en id-row med identity, men id'er skal kopieres med uændret.

Nogen der har nogle funktioner eller lignende til at klare sådan en opgave?
Avatar billede arne_v Ekspert
19. juli 2011 - 15:42 #1
Du kan scripte struktur i SQLServer Studio.

Import/eksport af data kan goeres paa flere maader. En af dem er at skrive dit eget lille kopierings program.
Avatar billede angelenglen Nybegynder
19. juli 2011 - 15:51 #2
Jeg burde måske have specificeret det lidt bedre, men regnede med det var nok at vælge kategori.

Jeg har brug for at kunne udføre opgaven som en del af min VB.NET applikation, skrevet i Visual Studio 2010.
Avatar billede angelenglen Nybegynder
19. juli 2011 - 15:56 #3
Forresten: Antallet af felter i tabellerne er ikke fastlagt, det kan ændre sig løbende, ligeledes kan felt-navnene.

Navnene på tabellerne er dog fastlagt og vil ikke ændre sig.
Avatar billede arne_v Ekspert
19. juli 2011 - 16:05 #4
Det er ikke te problem at finde en tabelstruktur via kode og at oprette tabeller eller rette struktur af en eksisterende tabel.
Avatar billede angelenglen Nybegynder
19. juli 2011 - 16:12 #5
Det lyder rigtigt godt.

Har du nogle funktioner der kan hjælpe med det, eller nogle links til den slags?

Jeg har ledt en del, men har ikke fundet brugbart endnu :-/
Avatar billede arne_v Ekspert
19. juli 2011 - 18:05 #6
SELECT * FROM INFORMATION_SCHEMA.COLUMNS

vil give dig informationer om hvilke kolonner der er i hvilke tabeller, deres typer etc..
Avatar billede angelenglen Nybegynder
20. juli 2011 - 09:08 #7
ok, jeg havde bare håbet på ikke at skulle genopfinde hjulet.
Avatar billede arne_v Ekspert
20. juli 2011 - 18:21 #8
Der findes DBA tools til den slags.

Men skal det goeres i din app, saa tror jeg at du bliver noedt til at kode det.
Avatar billede angelenglen Nybegynder
20. juli 2011 - 18:34 #9
Det er jeg desværre godt klar over, det var derfor jeg oprettede dette spørgsmål i første omgang.

Jeg finder det bare svært at tro at jeg er den første der nogensinde skal kode den slags, og havde derfor håbet at andre ville dele ud af den erfaring.

For det er jo langt fra så simpelt som at køre en select på information_schema, der er langt flere ting der skal tages højde for, som fx indexes, primary keys, identity columns, om null-værdier er tilladt osv.
Og det er kun for selve tabel-strukturen.

Så kommer data-rows efterfølgende, med dertilhørende problemstillinger og udfordringer.

Jeg finder nok ud af det, men det er bare ærgerligt at måtte bruge en måned på trial & error, for at opnå noget som jeg er sikker på mange andre har gjort mange gange før.
Avatar billede arne_v Ekspert
20. juli 2011 - 23:51 #10
key og indexes er ogsaa i information schemas.

check http://msdn.microsoft.com/en-us/library/ms186778.aspx

det er muligt at der er et smart lib til det, men jeg kender det ikke
Avatar billede angelenglen Nybegynder
10. august 2011 - 10:49 #11
Jeg fik det nogenlunde til at virke, men det blev langt fra så universalt som jeg havde håbet på :-(

Og den kode jeg fik lavet, er desværre ikke pæn nok til at jeg har lyst til at udstille den her :-/
Avatar billede angelenglen Nybegynder
10. august 2011 - 10:49 #12
arne_v: Du må lægge et svar, hvis du vil have nogle points :-D
Avatar billede arne_v Ekspert
11. august 2011 - 02:35 #13
svar
Avatar billede arne_v Ekspert
11. august 2011 - 02:47 #14
Noget C# kode fra lageret:

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

namespace E
{
    public class DbDump
    {
        public static void DumpTbl(IDbConnection con, string db, string tbl)
        {
            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())
            {
                Console.Write("INSERT INTO " + tbl + " VALUES(");
                for(int i = 0; i < rdr.FieldCount; i++)
                {
                    if(i > 0) Console.Write(",");
                    object o = rdr[i];
                    if(o is DBNull)
                    {
                        Console.Write("NULL");
                    }
                    else if(o is int
                            || o is long
                            || o is float
                            || o is double
                            || o is decimal)
                    {
                        Console.Write(o);
                    }
                    else if(o is string)
                    {
                        Console.Write("'" + o.ToString().Replace("'", "''") + "'");
                    }
                    else
                    {
                        throw new ApplicationException("Unsupported data type");
                    }
                }
                Console.WriteLine(");");
            }
            rdr.Close();
        }
        public static void DumpDb(IDbConnection con, string db, string dbname)
        {
            Console.WriteLine("USE " + db + ";");
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_" + dbname + "='" + db + "' AND TABLE_TYPE='BASE TABLE'";
            List<string> alltbl = new List<string>();
            IDataReader rdr = cmd.ExecuteReader();
            while(rdr.Read())
            {
                alltbl.Add((string)rdr[0]);
            }
            rdr.Close();
            foreach(string tbl in alltbl)
            {
                DumpTbl(con, db, tbl);
            }
        }
        public static void Dump(IDbConnection con, string dbname)
        {
            IDbCommand cmd = con.CreateCommand();
            cmd.CommandText = "SELECT DISTINCT TABLE_" + dbname + " 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"))
                {
                    alldb.Add(db);
                }
            }
            rdr.Close();
            foreach(string db in alldb)
            {
                DumpDb(con, db, dbname);
            }
        }
        public static void Dump(string provider, string constr, string dbname)
        {
            DbProviderFactory dbf = DbProviderFactories.GetFactory(provider);
            using(IDbConnection con = dbf.CreateConnection())
            {
                con.ConnectionString = constr;
                con.Open();
                Dump(con, dbname);
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            DbDump.Dump("System.Data.SqlClient", @"Server=ARNEPC3\SQLEXPRESS;Integrated Security=SSPI;Database=Test", "CATALOG");
            DbDump.Dump("MySql.Data.MySqlClient", "Data Source=localhost;Database=Test;User Id=root;Password=", "SCHEMA");
        }
    }
}
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
Kategori
Kurser inden for grundlæggende programmering

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