Миграция данных из PostgreSQL 8.3 в SQL Server 2008 R2 Standard Edition.
Сначала я попытался прилинковать PostgreSQL к SQL Server, используя оригинальный драйвер ODBC. Когда создавал соединение, все было хорошо, т.е. Test Connection проходил, но при попытке линка вываливалась ошибка. Я не стал особо копать, т.к. знаю, что ODBC - один из самых глючных способов линковки к SQL Server. Проблемы возникают даже когда к одному SQL Server линкуется другой SQL Server.
Далее я начал искать другие дрова. Первыми нашел вот это http://pgfoundry.org/frs/?group_id=1000085&release_id=539 , но не стал качать, т.к. смутила дата последнего релиза - 17.04.2006.
Далее на сайте PostgreSQL я нашел список различных дров: http://www.postgresql.org/download/products/2. По описанию мне понравились вот эти PGNP, я пробовал, работает отлично, порадовало так же поддержка SSIS, но из-за платности, я от них отказался.
Далее мой выбор пал на продукт, под названием Npqsql, по сути это библиотека для .Net, бесплатная, на ней я и остановился, но для миграции данных потребовалось написать код на C#:
using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.IO;
using Npgsql;
namespace Zapuskatr
{
class Program
{
static string COLS_DELIMITER = "|";
static string ROW_DELIMITER = "\n";
static string CNN_STRING = null;
static string QUERY = null;
static string PATH = null;
static void Main(string[] args)
{
if (CNN_STRING == null)
{
Console.WriteLine("ERROR: Connection string is empty.");
return;
}
NpgsqlConnection cnn = null;
NpgsqlCommand cmd = null;
NpgsqlDataReader reader = null;
try
{
cnn = new NpgsqlConnection(CNN_STRING);
cnn.Open();
if (QUERY != null)
{
cmd = new NpgsqlCommand(QUERY, cnn);
reader = cmd.ExecuteReader();
int columns = reader.FieldCount;
if (PATH == null)
{
while (reader.Read())
{
Console.Write(reader[0].ToString());
for (int i = 1; i < columns; i++)
{
Console.Write(COLS_DELIMITER + reader[i].ToString());
}
Console.Write(ROW_DELIMITER);
}
}
else
{
StreamWriter sw = new StreamWriter(PATH, false);
while (reader.Read())
{
sw.Write(reader[0].ToString());
for (int i = 1; i < columns; i++)
{
sw.Write(COLS_DELIMITER + reader[i].ToString());
}
sw.Write(ROW_DELIMITER);
}
sw.Flush();
sw.Close();
}
cmd.Dispose();
}
else
Console.WriteLine("Version: {0}", cnn.ServerVersion);
}
catch (Exception ex)
{
Console.WriteLine("ERROR: {0}", ex.Message);
}
finally
{
cnn.Close();
}
}
}
}
Консольная программа - если PATH не задан, то выводит в консоль. Если QUERY не задан, то выводит версию PostgreSQL. COLS_DELIMITER - разделитель колонок, ROW_DELIMITER - разделитель строк. Код сам определяет количество колонок в запросе и выводит их все.
Далее, основываясь на этом коде, я создавал CSV файлы и с помощью SSIS закачивал их в SQL Server.