SqlBulkCopy berechnetes Feld

.net c# ms-access sqlbulkcopy sql-server

Frage

Ich arbeite daran, eine Datenbank von MS Access auf SQL Server zu verschieben. Um die Daten in die neuen Tabellen zu verschieben, habe ich beschlossen, eine Synchronisierungsroutine zu schreiben, da sich das Schema ziemlich signifikant geändert hat. Ich kann Tests auf Programmen ausführen, die daraus ausgeführt werden, und Resynchronisierungen durchführen, wenn neue Testdaten benötigt werden. Dann werde ich schließlich eine letzte Synchronisierung durchführen und live auf der neuen SQL Server-Version starten.

Leider habe ich einen Haken gefunden, meine Methode ist unten zum Kopieren von Access auf 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;
            }
        }
    }

Im Grunde wird der Zugriff für die Daten mit der Eingabe-SQL-Zeichenfolge abgefragt, die alle korrekten Feldnamen enthält, so dass ich keine Spaltenzuordnungen festlegen muss.

Das funktionierte, bis ich einen Tisch mit einem berechneten Feld erreichte. SQLBulkCopy scheint nicht zu wissen, das Feld zu überspringen und versucht, die Spalte zu aktualisieren, die mit Fehler fehlschlägt. "Die Spalte 'columnName' kann nicht geändert werden, da es entweder eine berechnete Spalte ist oder das Ergebnis eines Vereinigungsoperators ist."

Gibt es eine einfache Möglichkeit, das berechnete Feld zu überspringen?

Ich hoffe, dass ich keine vollständige Spaltenzuordnung angeben muss.

Akzeptierte Antwort

Es gibt zwei Möglichkeiten, dem auszuweichen:

  • Verwenden Sie die ColumnMappings , um die Spaltenbeziehung formal zu definieren (Sie merken, dass Sie das nicht möchten)
  • Verschieben Sie die Daten in eine Staging-Tabelle - eine Basistabelle, die nicht zu Ihren Kerntransaktionstabellen gehört und deren gesamter Zweck genau so aussieht wie dieser Datenimport. Verwenden Sie dann einen TSQL-Befehl, um die Daten aus der Staging-Tabelle in die reale Tabelle zu übertragen

Ich bevorzuge die zweite Option aus verschiedenen Gründen:

  • Ich muss mich nie mit Mappings anlegen - das ist mir eigentlich wichtig, p
  • Die Einfügung in die reale Tabelle wird vollständig protokolliert ( SqlBulkCopy wird nicht unbedingt protokolliert)
  • Ich habe die schnellste Eingabe - keine Einschränkungsprüfung, keine Indexierung usw
  • Ich binde während des Imports keine Transaktionstabelle und es besteht keine Gefahr, dass nicht wiederholbare Abfragen mit einer teilweise importierten Tabelle ausgeführt werden
  • Ich habe eine sichere Abbruchoption, wenn der Import auf halbem Weg fehlschlägt, ohne Transaktionen zu verwenden (nichts hat das Transaktionssystem an dieser Stelle berührt)
  • Es ermöglicht ein gewisses Maß an Datenverarbeitung, wenn es in die realen Tabellen IDataReader , ohne dass entweder alles in einer DataTable auf der App-Ebene IDataReader muss oder ein benutzerdefinierter IDataReader implementiert werden IDataReader


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum