Перенос данных с MySQL на SQL Express. Часть II. .NET Provider.

С оригиналом поста можно ознакомиться в блоге Алексея Шуленина https://blogs.msdn.com/alexejs/archive/2009/06/17/mysql-sql-express-ii-net-provider.aspx

 

В этом посте мы рассмотрим альтернативный ODBC (см. Перенос данных с MySQL на SQL Express. Часть I. ODBC) способ переноса данных из MySQL на SQL Server, который использует MySQL Connector/Net 6.0 (https://dev.mysql.com/downloads/connector/net/6.0.html). Из списка предложенных вариантов пакета установки (исходники, Windows Binaries и Windows Binaries без инсталлятора) я как человек избалованный, выбрал второй. От предложения зарегистрироваться на сайте MySQL.com любезно отказался, а то еще неправильно поймут, увидев microsoftовский e-mail, и сразу жмакнул внизу на No thanks, just take me to the downloads. Не обнаружив российской площадки для скачивания, по привычке выбрал германскую. До этого у меня стояла аналогичная штуковина предыдущей версии (5.2), перед установкой 6.0 я ее снес от греха.

image001

рис.1

, после чего поставил свежую версию

image003

image005

image007

рис.2

Минуты 3 этот экран висел с сообщением Reconfiguring Visual Studio 2008. Все остальное заняло копейки. MySQLный дотнетовский коннектор появляется в соответствующей группе программ в стартовом меню.

image009

рис.3

Я создал от балды файл aaa.udl, кликнул на него два раза и посмотрел, что добавилось в списке установленных OLE DB-провайдеров. Список провайдеров остался прежний.

 

image011

рис.4

Ничего навевающего мысли об MySQL в нем не появилось. .NET Provider для MySQL под словом провайдер понимает добавление примочек к Visual Studio. Он добавляет новые пространства имен MySql.Data в .NET, что позволяет работать c MySQL из Visual Studio столь же элегантно, как с SQL Server при помощи System.Data.SqlClient

image013

рис.5

, но при этом, вероятно, использует прямой доступ к телу, подобно SQL Native Client, так что в плане OLE DB-провайдеров никаких новшеств не привносит, следовательно, сказать что-то новое про создание прилинкованного сервера по сравнению с предыдущим постом я не могу. Что ж, будем использовать Visual Studio. Задача остается прежней. Данные из таблицы на MySQL требуется перетащить в аналогичную таблицу SQL Server. В качестве первого приближения у меня получился следующий код

using System;

using MySql.Data.MySqlClient;

using System.Data;

using System.Data.SqlClient;

class Program

{

    static void Main(string[] args)

    {

        string tblName = "b_learn_lesson";

       

        MySqlConnection mySqlCnn = new MySqlConnection("server=127.0.0.1;port=31006;uid=root;pwd=;database=bsm_demo;Pooling=False");

        mySqlCnn.Open();

        MySqlCommand mySqlCmd = new MySqlCommand("select * from " + tblName, mySqlCnn);

        MySqlDataReader mySqlDr = mySqlCmd.ExecuteReader();

        SqlConnection sqlSrvCnn = new SqlConnection(@"server=(local)\SQLExpress;database=bitrix;trusted_connection=true");

        sqlSrvCnn.Open();

        SqlBulkCopy bcp = new SqlBulkCopy(sqlSrvCnn, SqlBulkCopyOptions.KeepIdentity, null);

        //Если колонки не совпадают, - bcp.ColumnMappings.Add(<название колонки источника>, <название колонки назначения>)

        bcp.DestinationTableName = tblName;

        bcp.WriteToServer(mySqlDr);

        mySqlDr.Close();

        mySqlCnn.Close();

        sqlSrvCnn.Close();

    }

}

Скрипт 1

Открываем соединение с MySQL, открываем ридер на чтение заданной таблицы, открываем соединение с SQL Server и заправляем шланг ридера объекту SqlBulkCopy, чтобы он качал из него содержимое в bcp.DestinationTableName. Флаг SqlBulkCopyOptions.KeepIdentity означает, что колонка автоинкремента в назначении не заполняется сама при вставке копируемых записей, а в нее тупо копируются данные из соответствующей колонки источника, т.е. автоинкремент на время копирования отключается, а потом опять включается. Короче, делается set identity_insert b_learn_lesson on/off. Коллекция ColumnMappings – это, типа, стрелочки в Data Transform Task – какое поле в какое копируем. Только DTS по умолчанию связывает их на основе совпадения имен, а эта хрень – тупо по порядковому номеру колонки: первая в источнике соответствует первой в назначении и т.д. Если порядок полей различен, нужно явно протягивать стрелочки (наполнять коллекцию ColumnMappings), либо явно перечислять поля в нужном порядке в команде select из источника, над которой потом строится MySqlDataReader. Дополнительную информацию про класс SqlBulkCopy можно почерпнуть здесь - http.

Идем в SQL Server Management Studio (SSMS), готовим таблицу-приемник и тестируем прогу:

use bitrix

delete from dbo.B_LEARN_LESSON

--Пускаем прогу в Visual Studio

select * from dbo.B_LEARN_LESSON

image015

рис.6

По-моему, работает. Обратите внимание, что B_LEARN_LESSON – это та самая таблица, на которой у нас в предыдущем посте вылетал MySQLный ODBC-драйвер, столкнувшись с полем типа longtext. .NET Connector ведет себя в этом плане приличней.