2009-08-26 4 views
1

J'essaie de transférer les données de SQLite vers SQL Server. Le schéma de la cible et la table de destination sont les mêmes:Importer des données de SQLite vers SQL Server avec la classe SqlBulkCopy

SQL Server:

CREATE TABLE [dbo].[Shop] (
    [ShopID] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [nvarchar](128) NOT NULL, 
    [Url] [nvarchar](128) NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [ShopID] ASC 
)) 

et SQLite:

CREATE TABLE "Shop" (
    "ShopID" INTEGER PRIMARY KEY NOT NULL, 
    "Name" VARCHAR NOT NULL, 
    "Url" VARCHAR NOT NULL); 

j'ai écrit le code comme ci-dessous (avec System.Data.SQLite) :

using (var conn = new SQLiteConnection(@"Data Source=Data.sqlite;FailIfMissing=True")) 
{ 
    conn.Open(); 
    var cmd = new SQLiteCommand("SELECT * FROM Shop", conn); 
    var reader = cmd.ExecuteReader(); 

    using (var bulkCopy = new SqlBulkCopy("Data Source=.;Initial Catalog=Test;Integrated Security=True")) 
    { 
     bulkCopy.DestinationTableName = "Shop"; 
     bulkCopy.ColumnMappings.Add("ShopID", "ShopID"); 
     bulkCopy.ColumnMappings.Add("Name", "Name"); 
     bulkCopy.ColumnMappings.Add("Url", "Url"); 
     bulkCopy.WriteToServer(reader); 
    } 
} 

Les données ont été chargées par le lecteur (j'ai vérifié). Mais une InvalidOperationException jette sur la méthode WriteToServer: Le ColumnMapping donné ne correspond à aucune colonne dans la source ou la destination.

Des idées ou des suggestions pour moi?

+1

Ai-je tort ou ce ColumnMappings.Add n'est pas nécessaire? Les deux tables sont identiques ... –

Répondre

1

Cela peut résoudre ou non votre problème, mais vous souhaiterez probablement utiliser SqlBulkCopyOptions pour spécifier que vous ne souhaitez pas qu'il génère de nouvelles valeurs d'identité.

SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.KeepIdentity)) 
0

Cela fonctionne pour moi ...

private void GatherDb3Info(FileInfo[] fiDb3) { 
     SQLiteConnectionStringBuilder csb = new SQLiteConnectionStringBuilder(); 
     foreach (FileInfo fi in fiDb3) { 
      csb.Clear(); 
      csb.DataSource = fi.FullName; 
      csb.Password = "[email protected]$$w0rd"; 
      csb.SyncMode = SynchronizationModes.Full; 

      using (var conn = new SQLiteConnection(csb.ToString())) { 
       conn.Open(); 
       DataTable dtTables = conn.GetSchema(SQLiteMetaDataCollectionNames.Tables, new String[] { }); 
       foreach (DataRow dRow in dtTables.Rows) { 
        if (dRow["Table_Type"].ToString().ToLower() != "table") continue; 
        String 
         catName = String.Format("{0}", dRow["Table_Catalog"]), 
         schName = String.Format("{0}", dRow["Table_Schema"]), 
         tblName = String.Format("{0}", dRow["Table_Name"]); 
        DataTable dtColumns = conn.GetSchema(SQLiteMetaDataCollectionNames.Columns, new System.String[] { catName, schName, tblName }); 
        StringBuilder sb = new StringBuilder(); 
        foreach (DataRow dRowColumn in dtColumns.Rows) { 
         sb.AppendFormat("[{0}], ", dRowColumn["Column_Name"]); 
        } 

        String sColList = sb.ToString(); 
        sColList = sColList.Remove(sColList.Length - 2); 
        var cmd = new SQLiteCommand("Select " + sColList + " From " + tblName, conn); 
        var reader = cmd.ExecuteReader(); 
        using (var bulkCopy = new System.Data.SqlClient.SqlBulkCopy(@"Server=.;Integrated Security=true;Database=TargetDBName;")) { 
         bulkCopy.DestinationTableName = "TargetTableSchema." + tblName; 
         try { 
          bulkCopy.WriteToServer(reader); 
         } catch (Exception) { } 
        } 
       } 
       conn.Close(); 
      } 
     } 
    } 
+1

Ce bloc catch vide va vous donner un gros mal de tête s'il y a une erreur et vous ne le savez pas. Peut-être que c'est pour ça que tu dis "ça marche". Qui sait? – usr

Questions connexes