Вводные данные
-
Сервер: Windows Server 2003 R2 x86
-
Источник: Interbase (производственная база)
-
Приёмник: SQL Server 2008 Express x86
-
Клиент: 1С (выгрузка/синхронизация через SQL Server)
Цель: синхронизировать данные либо периодически затягивать их из Interbase в SQL Server для последующего использования в 1С.
1. Установка и настройка ODBC-драйвера Firebird
-
Скачайте ODBC-драйвер Firebird версии 2.0.3 или 2.0.5 (стабильные для Interbase).
-
Установите драйвер на сервере, где будет работать SQL Server.
Примечание: даже если целевая БД — Interbase, драйвер Firebird ODBC подходит (они совместимы на уровне протокола), а за оригинальные дрова просят доллары.
2. Создание системного DSN
-
Откройте Администрирование → Источники данных ODBC.
-
Перейдите на вкладку Системный DSN.
-
Нажмите Добавить → выберите драйвер
Firebird/InterBase ODBC. -
Настройте подключение:
-
Имя DSN (например,
INTERBASE_DSN) -
В строке Database укажите путь к файлу
.gdbили.fdb, обязательно добавив в началоимя_сервера:илиlocalhost:
Пример:localhost:C:\Database\PROD.GDB
Если этого не сделать, Interbase может не пустить подключение.
-
-
Задайте остальные параметры (кодировка – обычно
WIN1251для кириллицы, пользовательSYSDBA, парольmasterkey). -
Сохраните DSN.
3. Установка SQL Server 2008 Express x86
-
Установите SQL Server 2008 Express (32-разрядная версия, даже если ОС 64-бит – для совместимости с драйвером).
-
В процессе установки выберите смешанный режим аутентификации (
sa+ пароль). -
Запомните имя экземпляра (например,
MSSQLSERVERилиSQLEXPRESS).
4. Создание связанного сервера к Interbase через ODBC
Выполните в SQL Server Management Studio (или в sqlcmd) следующий скрипт:
-- 1. Создаём связанный сервер
EXEC sp_addlinkedserver
@server = N'INTERBASE_LINK', -- Имя для запросов
@srvproduct = N'InterBase',
@provider = N'MSDASQL',
@datasrc = N'INTERBASE_DSN'; -- Имя вашего системного DSN
GO
-- 2. Настраиваем учётные данные для подключения к Interbase
EXEC sp_addlinkedsrvlogin
@rmtsrvname = N'INTERBASE_LINK',
@useself = N'False',
@locallogin = NULL,
@rmtuser = N'SYSDBA',
@rmtpassword = N'masterkey';
GO
5. Настройка SQL Server для доступа из 1С
Чтобы сервер 1С «увидел» SQL Server:
-
Откройте SQL Server Configuration Manager.
-
В разделе Сетевые конфигурации SQL Server выберите Протоколы для вашего экземпляра.
-
Включите TCP/IP (и перезапустите службу SQL Server).
-
Включите службу SQL Server Browser (она должна быть запущена, чтобы отвечать на запросы по именам экземпляров).
6. Разрешение удалённого вызова процедур (RPC)
Выполните в SQL Server:
EXEC sp_serveroption 'INTERBASE_LINK', 'rpc', 'true';
EXEC sp_serveroption 'INTERBASE_LINK', 'rpc out', 'true';
Это позволит выполнять хранимые процедуры на связанном сервере и получать результаты.
7. Создание обёрточной хранимой процедуры для записи данных
Проблема: при прямом вызове OPENQUERY или EXEC AT из 1С возникают трудности с кодировками (WIN1251 ↔ UTF-16) и экранированием кавычек.
Решение: создаём на SQL Server процедуру, которая формирует динамический SQL и выполняет его через связанный сервер.
CREATE PROCEDURE dbo.InsertOrderToInterbase
@OrderNo INT,
@Customer VARCHAR(200),
@FinishDate DATETIME,
@Issue INT,
@OrderSubNo VARCHAR(15),
@WaitedOrder SMALLINT = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DateStr VARCHAR(25) = CONVERT(VARCHAR(25), @FinishDate, 120);
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'EXEC (''INSERT INTO ORDERS (ORDER_NO, CUSTOMER, FINISH_DATE, ISSUE, ORDER_SUBNO, WAITED_ORDER) '
+ N'VALUES ('
+ CAST(@OrderNo AS VARCHAR(10)) + N', '
+ N'_WIN1251''''' + REPLACE(@Customer, '''', '''''') + N''''', '
+ N'''''' + @DateStr + N''''', '
+ CAST(@Issue AS VARCHAR(10)) + N', '
+ N'_WIN1251''''' + REPLACE(@OrderSubNo, '''', '''''') + N''''', '
+ CAST(@WaitedOrder AS VARCHAR(5)) + N')'') AT INTERBASE_LINK';
EXEC sp_executesql @SQL;
END;
💡 Пояснение:
_WIN1251перед строкой – это указание Interbase на кодировку. Без этого кириллица превратится в «крокозябры».
8. Вызов процедуры из 1С (запись в Interbase)
&НаСервере
Процедура ЗаписатьСтрокуДанныхВInterBase(Connection)
Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandText = "dbo.InsertOrderToInterbase";
Command.CommandType = 4; // adCmdStoredProc
// Параметры (порядок и типы должны совпадать с определением процедуры)
Command.Parameters.Append(Command.CreateParameter("@OrderNo", 3, 1, , НомерЗаказа));
Command.Parameters.Append(Command.CreateParameter("@Customer", 200, 1, 200, ИмяКлиента));
Command.Parameters.Append(Command.CreateParameter("@FinishDate", 7, 1, , ДатаЗавершения));
Command.Parameters.Append(Command.CreateParameter("@Issue", 3, 1, , НомерИшью));
Command.Parameters.Append(Command.CreateParameter("@OrderSubNo", 200, 1, 15, ПодномерЗаказа));
Command.Parameters.Append(Command.CreateParameter("@WaitedOrder", 2, 1, , ЖдатьЗаказ));
Command.Execute();
КонецПроцедуры
9. Чтение данных из Interbase через SQL Server (пример для 1С)
Чтение проще записи – используем OPENQUERY:
&НаСервере
Процедура SQLLinkНаСервере()
// Подключение к SQL Server (не к Interbase!)
СтрокаПодкл = "Provider=MSOLEDBSQL;Data Source=ИМЯ_СЕРВЕРА_SQL;Initial Catalog=master;User ID=sa;Password=пароль;";
ЗапросInterbase = "SELECT ORDER_NO, ORDER_SUBNO, CUSTOMER, FINISH_DATE, ISSUE FROM ORDERS ROWS 1 TO 50";
ОберткаSQL = "SELECT * FROM OPENQUERY(INTERBASE_LINK, '%1')";
ТекстSQL = СтрШаблон(ОберткаSQL, ЗапросInterbase);
Connection = Новый COMОбъект("ADODB.Connection");
Connection.Open(СтрокаПодкл);
RecordSet = Connection.Execute(ТекстSQL);
ТаблицаЗаписей = RecordSetВТаблицуЗначений(RecordSet);
Для Каждого СтрокаЗаписи Из ТаблицаЗаписей Цикл
Сообщить(СтрШаблон("ORDER_NO=%1, CUSTOMER=%2", СтрокаЗаписи[0], СтрокаЗаписи[2]));
КонецЦикла;
Сообщить("Количество записей: " + ТаблицаЗаписей.Количество());
RecordSet.Close();
Connection.Close();
КонецПроцедуры
10. Функция преобразования RecordSet → ТаблицаЗначений
Функция RecordSetВТаблицуЗначений(RecordSet)
ТЗ = Новый ТаблицаЗначений;
// 1. Создаём колонки
Для Каждого Поле Из RecordSet.Fields Цикл
ИмяКолонки = СтрЗаменить(Поле.Name, " ", "_"); // пробелы заменяем
ТЗ.Колонки.Добавить(ИмяКолонки);
КонецЦикла;
// 2. Заполняем строки
Пока НЕ RecordSet.EOF Цикл
НоваяСтрока = ТЗ.Добавить();
Для Каждого Поле Из RecordSet.Fields Цикл
ИмяКолонки = СтрЗаменить(Поле.Name, " ", "_");
НоваяСтрока[ИмяКолонки] = Поле.Value;
КонецЦикла;
RecordSet.MoveNext();
КонецЦикла;
Возврат ТЗ;
КонецФункции
Вступайте в нашу телеграмм-группу Инфостарт