SqlBulkCopy champ calculé

.net c# ms-access sqlbulkcopy sql-server

Question

Je travaille sur le déplacement d'une base de données de MS Access vers un serveur SQL. Pour déplacer les données dans les nouvelles tables, j'ai décidé d'écrire une routine de synchronisation car le schéma a considérablement changé et me permet de tester des programmes qui l'exécutent et de les resynchroniser chaque fois que j'ai besoin de nouvelles données de test. Ensuite, je ferai une dernière synchronisation et commencerai en direct sur la nouvelle version du serveur SQL.

Malheureusement, j'ai eu un problème, ma méthode est la suivante pour copier d'Access to SQLServer

public static void BulkCopyAccessToSQLServer
        (string sql, CommandType commandType, DBConnection sqlServerConnection,
            string destinationTable, DBConnection accessConnection, int timeout)
    {
        using (DataTable dt = new DataTable())
        using (OleDbConnection conn = new OleDbConnection(GetConnection(accessConnection)))
        using (OleDbCommand cmd = new OleDbCommand(sql, conn))
        using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
        {
            cmd.CommandType = commandType;
            cmd.Connection.Open();
            adapter.SelectCommand.CommandTimeout = timeout;
            adapter.Fill(dt);

            using (SqlConnection conn2 = new SqlConnection(GetConnection(sqlServerConnection)))
            using (SqlBulkCopy copy = new SqlBulkCopy(conn2))
            {
                conn2.Open();

                copy.DestinationTableName = destinationTable;
                copy.BatchSize = 1000;
                copy.BulkCopyTimeout = timeout;
                copy.WriteToServer(dt);
                copy.NotifyAfter = 1000;
            }
        }
    }

Fondamentalement, cette requête concerne l'accès aux données à l'aide de la chaîne SQL d'entrée. Elle contient tous les noms de champs corrects; il n'est donc pas nécessaire de définir des mappages de colonnes.

Cela fonctionnait jusqu'à ce que j'atteigne une table avec un champ calculé. SQLBulkCopy ne semble pas savoir ignorer le champ et tente de mettre à jour la colonne qui échoue avec l'erreur "La colonne 'NomColonne' ne peut pas être modifiée car il s'agit d'une colonne calculée ou du résultat d'un opérateur d'union."

Existe-t-il un moyen simple de faire sauter le champ calculé?

J'espère ne pas avoir à spécifier un mappage de colonne complet.

Réponse acceptée

Il y a deux façons d'éviter cela:

  • utilisez les ColumnMappings pour définir formellement la relation de colonne (vous notez que vous ne le souhaitez pas)
  • poussez les données dans une table intermédiaire - une table de base, ne faisant pas partie de vos tables transactionnelles principales, ayant pour seul but de ressembler exactement à cette importation de données; utilisez ensuite une commande TSQL pour transférer les données de la table de transfert vers la table réelle

Je privilégie toujours la deuxième option, pour différentes raisons:

  • Je n'ai jamais à jouer avec les cartographies - c'est en fait important pour moi; p
  • l'insertion dans la table réelle sera entièrement enregistrée ( SqlBulkCopy n'est pas nécessairement enregistré)
  • J'ai l'insertion la plus rapide possible - pas de vérification de contrainte, pas d'indexation, etc.
  • Je n'attache pas de table transactionnelle lors de l'importation et il n'y a aucun risque que des requêtes non répétables soient exécutées sur une table partiellement importée.
  • J'ai une option d'abandon sûr si l'importation échoue à mi-parcours, sans avoir à utiliser de transactions (rien n'a touché le système transactionnel à ce stade)
  • il permet un certain niveau de traitement de données lors de l'insertion dans les tables réelles, sans qu'il soit nécessaire de tout mettre en mémoire tampon dans un DataTable au niveau de l'application, ni d'implémenter un IDataReader personnalisé IDataReader


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi