Импорт данных из Excel в Microsoft SQL Server на языке T-SQL

Microsoft SQL Server позволяет встроенными средствами языка T-SQL в SQL запросе импортировать данные из файла Excel в базу данных. Сегодня я подробно расскажу, как это делается, какие условия необходимо выполнить, чтобы эта операция проходила успешно, расскажу про особенности импорта для самых распространённых случаев конфигураций SQL сервера и приведу конкретный порядок действий и практические примеры.

Импорт данных из Excel в Microsoft SQL Server

Начну я с того, что импортировать данные из Excel в Microsoft SQL Server можно с помощью «Распределенных запросов» и с помощью «Связанных серверов». Это, скорей всего, Вы уже знаете, так как я уже не раз писал об этом (ссылки на соответствующие материалы указаны чуть выше).

Обратиться к файлу Excel и импортировать данные в Microsoft SQL Server можно с помощью T-SQL инструкций OPENDATASOURCE, OPENROWSET или OPENQUERY.

Однако в вышеупомянутых статьях я упустил несколько важных моментов, одним из которых является то, что у всех конфигурация SQL сервера разная, за счет чего у многих возникают различные проблемы и появляются ошибки во время выполнения распределенных запросов и обращений к связанным серверам. Также я описывал способ загрузки данных из Excel, который на сегодняшний день уже устарел, поэтому сегодня я постараюсь дать Вам немного больше информации о том, как импортировать данные из файла Excel в Microsoft SQL Server на языке T-SQL.

Содержание
  1. Введение
  2. Импорт данных из Excel 2003 (файл xls) в Microsoft SQL Server x86
  3. Шаг 1 – Проверяем наличие провайдера Microsoft.Jet.OLEDB.4.0 на SQL Server
  4. Шаг 2 – Предоставление прав пользователю на временный каталог
  5. Шаг 3 – Включаем распределенные запросы на SQL Server
  6. Шаг 4 – Выполняем SQL запрос, обращение к файлу Excel
  7. Импорт данных из Excel 2007 и выше (файл xlsx) в Microsoft SQL Server x86
  8. Шаг 1 – Проверяем наличие провайдера Microsoft.ACE.OLEDB.12.0 на SQL Server
  9. Шаг 2 – Установка провайдера Microsoft.ACE.OLEDB.12.0 (32-bit)
  10. Шаг 3 – Предоставление прав пользователю на временный каталог
  11. Шаг 4 – Включаем распределенные запросы на SQL Server
  12. Шаг 5 – Настройка провайдера Microsoft.ACE.OLEDB.12.0
  13. Шаг 6 – Выполняем SQL запрос, обращение к файлу Excel
  14. Импорт данных из Excel (любые файлы) в Microsoft SQL Server x64
  15. Шаг 1 – Проверяем наличие провайдера Microsoft.ACE.OLEDB.12.0 на SQL Server
  16. Шаг 2 – Установка провайдера Microsoft.ACE.OLEDB.12.0 (64-bit)
  17. Шаг 3 – Включаем распределенные запросы на SQL Server
  18. Шаг 4 – Настройка провайдера Microsoft.ACE.OLEDB.12.0
  19. Шаг 5 – Выполняем SQL запрос, обращение к файлу Excel
  20. Подведение итогов

Введение

Итак, как я уже сказал, очень важную роль здесь играет конфигурация SQL сервера, в частности, какая версия сервера установлена, x86 или x64.

Если говорить о последних версиях Microsoft SQL Server 2016-2019, то они только x64 и устанавливаются на 64-разрядные версии Windows.

Исходя из этого я разделю статью на несколько частей, в каждой из которых я расскажу про особенности импорта данных из Excel для самых распространённых случаев конфигураций и приведу конкретный порядок действий.

Для того чтобы быстро узнать, какая версия SQL Server установлена у Вас на компьютере, можете выполнить простой SQL запрос

   
   SELECT @@VERSION;

Обращение к файлу Excel и, соответственно, импорт данных в Microsoft SQL Server происходит с помощью специальных провайдеров (поставщиков). Для работы с Excel в Microsoft SQL Server обычно используются:

  • Jet.OLEDB.4.0
  • ACE.OLEDB.12.0

Во всех примерах ниже я буду посылать простой запрос SELECT на выборку данных из Excel файла, для того чтобы проверить доступ к данным в файле Excel. Чтобы осуществить импорт данных (загрузить данные в БД), Вы можете использовать любой удобный для Вас способ, например, конструкцию SELECT INTO или INSERT INTO.

Дополнительно рекомендовано закрывать файл Excel во время обращения к нему в распределенных запросах, а также указывать путь к файлу без пробелов (хотя современный SQL сервер умеет работать с пробелами).

Импорт данных из Excel 2003 (файл xls) в Microsoft SQL Server x86

Шаг 1 – Проверяем наличие провайдера Microsoft.Jet.OLEDB.4.0 на SQL Server

Первое, с чего нам нужно начать, это проверить, зарегистрирован ли провайдер Microsoft.Jet.OLEDB.4.0 на SQL Server, так как в данном случае необходимо использовать именно этот провайдер. Это можно сделать с помощью следующей SQL инструкции

   
   EXEC sp_enum_oledb_providers;

В результирующем наборе данных должна присутствовать строка с Microsoft.Jet.OLEDB.4.0. Если такого провайдера нет, то скорей всего в системе нет установленного Excel 2003 и, соответственно, его нужно установить.

Шаг 2 – Предоставление прав пользователю на временный каталог

Особенностью распределённых запросов и работы со связанным серверами Excel в x86 версиях SQL Server является то, что независимо от имени какой учетной записи посылается SQL запрос к Excel, эта учетная запись должна иметь права на запись во временный каталог той учетной записи, под которой работает сама служба SQL Server.Так как поставщик OLE DB создает временный файл во время запроса во временном каталоге SQL Server, используя учетные данные пользователя, выполняющего запрос.

Таким образом, если служба SQL Server работает от имени или локальной, или сетевой службы, необходимо дать соответствующие права на временный каталог этих служб всем пользователям, которые будут посылать распределенные запросы и обращаться к связанному серверу Excel (если сервер работает от имени пользователя, который посылает SQL запросы, то такие права давать не требуется, они у него уже есть).

Это можно сделать с помощью встроенной утилиты командной строки icacls.

Например, для локальной службы команда будет выглядеть следующим образом.

   
   icacls C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp /grant UserName:(R,W)

Для сетевой службы

   
   icacls C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp /grant UserName:(R,W)

Вместо UserName укажите имя пользователя, который посылает запрос.

Шаг 3 – Включаем распределенные запросы на SQL Server

По умолчанию возможность использования распределённых запросов, в частности функций OPENDATASOURCE и OPENROWSET, в Microsoft SQL Server запрещена, поэтому данную возможность нужно сначала включить.

Она включается с помощью системной хранимой процедуры sp_configure, которая отвечает за системные параметры сервера. Нам необходимо параметру Ad Hoc Distributed Queries присвоить значение 1, для этого выполняем следующую SQL инструкцию.

   
   sp_configure 'show advanced options', 1;
   RECONFIGURE;
   GO
   sp_configure 'Ad Hoc Distributed Queries', 1;
   RECONFIGURE;
   GO

Шаг 4 – Выполняем SQL запрос, обращение к файлу Excel

Ниже я приведу несколько вариантов обращения к файлу Excel (TestExcel.xls).

OPENROWSET

   
   SELECT * FROM OPENROWSET 
   ( 
    'Microsoft.Jet.OLEDB.4.0', 
    'Excel 8.0; Database=D:\TestExcel.xls', 
    'SELECT * FROM [Лист1$]' 
   );

OPENDATASOURCE

   
   SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0', 
                                'Data Source=D:\TestExcel.xls; 
                                 Extended Properties=Excel 8.0')...[Лист1$];

Linked Server

   
   --Создание связанного сервера 
   EXEC sp_addlinkedserver @server = 'TEST_EXCEL', 
                           @srvproduct = 'Excel', 
                           @provider = 'Microsoft.Jet.OLEDB.4.0', 
                           @datasrc = 'D:\TestExcel.xls', 
                           @provstr = 'Excel 8.0;IMEX=1;HDR=YES;';   
   
   --Настройки безопасности (авторизации) 
   EXEC dbo.sp_addlinkedsrvlogin @rmtsrvname='TEST_EXCEL', 
                                 @useself= 'False', 
                                 @locallogin=NULL, 
                                 @rmtuser=NULL, 
                                 @rmtpassword=NULL;   
   
   --Обращение к связанному серверу 
   SELECT * FROM OPENQUERY (TEST_EXCEL, 'SELECT * FROM [Лист1$]'); 
   --или 
   SELECT * FROM TEST_EXCEL...[Лист1$];

Импорт данных из Excel 2007 и выше (файл xlsx) в Microsoft SQL Server x86

Шаг 1 – Проверяем наличие провайдера Microsoft.ACE.OLEDB.12.0 на SQL Server

Точно так же, как и в предыдущем примере, сначала проверяем, установлен ли у нас необходимый нам провайдер, в данном случае нам нужен Microsoft.ACE.OLEDB.12.0.

   
   EXEC sp_enum_oledb_providers;

Шаг 2 – Установка провайдера Microsoft.ACE.OLEDB.12.0 (32-bit)

Если провайдера нет, то его необходимо установить.

Вот ссылка на скачивание провайдера

https://www.microsoft.com/en-us/download/details.aspx?id=13255

Выберите и скачайте файл, соответствующий архитектуре x86 (т.е. в названии без x64).

Шаг 3 – Предоставление прав пользователю на временный каталог

В данном случае также даем права на временный каталог локальной или сетевой службы всем пользователям, которые будут посылать SQL запросы к файлу Excel.

Используем все ту же утилиту командной строки icacls.

Для локальной службы

    
   icacls C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp /grant UserName:(R,W)

Для сетевой службы

   
   icacls C:\Windows\ServiceProfiles\NetworkService\AppData\Local\Temp /grant UserName:(R,W)

Вместо UserName укажите имя пользователя, который посылает запрос.

Шаг 4 – Включаем распределенные запросы на SQL Server

Включаем возможность использования OPENDATASOURCE и OPENROWSET на Microsoft SQL Server, повторюсь, что по умолчанию данная возможность отключена.

   
   sp_configure 'show advanced options', 1;
   RECONFIGURE;
   GO
   sp_configure 'Ad Hoc Distributed Queries', 1;
   RECONFIGURE;
   GO

Шаг 5 – Настройка провайдера Microsoft.ACE.OLEDB.12.0

В данном случае дополнительно потребуется настроить провайдер Microsoft.ACE.OLEDB.12.0. Для этого включим следующие параметры провайдера (для отключения укажите 0 вместо 1).

   
   EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
   GO
   EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
   GO

Если не включать данные параметры, то, скорей всего, появится ошибка примерно следующего содержания

«Сообщение 7399, уровень 16, состояние 1, строка 25
Поставщик OLE DB «Microsoft.ACE.OLEDB.12.0» для связанного сервера «(null)» сообщил об ошибке. Поставщик не предоставил данных об ошибке.
Сообщение 7330, уровень 16, состояние 2, строка 25
Не удалось получить строку от поставщика OLE DB «Microsoft.ACE.OLEDB.12.0» для связанного сервера «(null)».»

Шаг 6 – Выполняем SQL запрос, обращение к файлу Excel

Примеры обращения к файлу Excel (TestExcel.xlsx).

OPENROWSET

   
   SELECT * FROM OPENROWSET
   (
    'Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0;
     Database=D:\TestExcel.xlsx',
     'SELECT * FROM [Лист1$]'
   );

OPENDATASOURCE

   
   SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
                                'Data Source=D:\TestExcel.xlsx;
                                 Extended Properties=Excel 12.0')...[Лист1$];

Linked Server

   
   --Создание связанного сервера
   EXEC sp_addlinkedserver @server = 'TEST_EXCEL',
                           @srvproduct = 'Excel',
                           @provider = 'Microsoft.ACE.OLEDB.12.0',
                           @datasrc = 'D:\TestExcel.xlsx',
                           @provstr = 'Excel 12.0;IMEX=1;HDR=YES;';

   --Настройки безопасности (авторизации)
   EXEC dbo.sp_addlinkedsrvlogin @rmtsrvname='TEST_EXCEL',
                                 @useself= 'False',
                                 @locallogin=NULL,
                                 @rmtuser=NULL,
                                 @rmtpassword=NULL;
   
   --Обращение к связанному серверу
   SELECT * FROM OPENQUERY (TEST_EXCEL, 'SELECT * FROM [Лист1$]');
   --или
   SELECT * FROM TEST_EXCEL...[Лист1$];

Импорт данных из Excel (любые файлы) в Microsoft SQL Server x64

Шаг 1 – Проверяем наличие провайдера Microsoft.ACE.OLEDB.12.0 на SQL Server

В данном случае мы также используем провайдер Microsoft.ACE.OLEDB.12.0, сначала проверяем, зарегистрирован ли он на сервере.

   
   EXEC sp_enum_oledb_providers;

Шаг 2 – Установка провайдера Microsoft.ACE.OLEDB.12.0 (64-bit)

В случае, если провайдер не установлен, его необходимо скачать и установить.

https://www.microsoft.com/en-us/download/details.aspx?id=13255

Скачиваем файл x64.

Шаг 3 – Включаем распределенные запросы на SQL Server

Необходимость включения возможности использования распределенных запросов (OPENDATASOURCE и OPENROWSET) на Microsoft SQL Server x64 также есть, поэтому сначала включаем ее, выполнив точно такую же инструкцию.

   
   sp_configure 'show advanced options', 1;
   RECONFIGURE;
   GO
   sp_configure 'Ad Hoc Distributed Queries', 1;
   RECONFIGURE;

GO

Шаг 4 – Настройка провайдера Microsoft.ACE.OLEDB.12.0

В этом случае, скорей всего, настройка провайдера не потребуется, поэтому сначала сразу пробуем выполнить SQL запросы (обратиться к данным в Excel), и если возникает ошибка (все с тем же сообщением 7399 и 7330), то пробуем включить параметры AllowInProcess и DynamicParameters (для отключения укажите 0 вместо 1).

   
   EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
   GO
   EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
   GO

Шаг 5 – Выполняем SQL запрос, обращение к файлу Excel

Здесь используются точно такие же параметры в SQL запросах, что и в предыдущем примере. Для удобства продублирую их еще раз.

Примеры обращения к файлу Excel (TestExcel.xlsx).

OPENROWSET

   
   SELECT * FROM OPENROWSET
   (
    'Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0;
     Database=D:\TestExcel.xlsx',
    'SELECT * FROM [Лист1$]'
   );

OPENDATASOURCE

   
   SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
                                'Data Source=D:\TestExcel.xlsx;
                                 Extended Properties=Excel 12.0')...[Лист1$];

Linked Server

   
   --Создание связанного сервера
   EXEC sp_addlinkedserver @server = 'TEST_EXCEL',
                           @srvproduct = 'Excel',
                           @provider = 'Microsoft.ACE.OLEDB.12.0',
                           @datasrc = 'D:\TestExcel.xlsx',
                           @provstr = 'Excel 12.0;IMEX=1;HDR=YES;';
   
   --Настройки безопасности (авторизации)
   EXEC dbo.sp_addlinkedsrvlogin @rmtsrvname='TEST_EXCEL',
                                 @useself= 'False',
                                 @locallogin=NULL,
                                 @rmtuser=NULL,
                                 @rmtpassword=NULL;
   
   --Обращение к связанному серверу
   SELECT * FROM OPENQUERY (TEST_EXCEL, 'SELECT * FROM [Лист1$]');
   --или
   SELECT * FROM TEST_EXCEL...[Лист1$];

Подведение итогов

Ну и в заключение я сгруппирую действия, которые необходимо выполнять в зависимости от выпуска SQL Server (x68 или x64) и версии файла Excel (xls или xlsx), в одну таблицу, для Вашего удобства.

Действие / Настройка Импорт Excel 2003 (файл xls) в SQL Server x86 Импорт Excel 2007 (файл xlsx) в SQL Server x86 Импорт Excel (любые файлы) в SQL Server x64
Установка Excel 2003 Да Нет Нет
Установка провайдера Microsoft.ACE.OLEDB.12.0 Нет Да (x86) Да (x64)
Предоставление прав на временный каталог служб (если SQL сервер работает от имени служб) Да Да Нет
Настройка провайдера Microsoft.ACE.OLEDB.12.0 Нет Да Нет (по необходимости)
Параметры подключения в SQL запросах Microsoft.Jet. OLEDB.4.0 и Excel 8.0 Microsoft.ACE. OLEDB.12.0 и Excel 12.0 Microsoft.ACE. OLEDB.12.0 и Excel 12.0
Включение распределённых запросов на SQL Server Да Да Да

Для комплексного изучения языка T-SQL начинающим рекомендую почитать мою книгу «Путь программиста T-SQL

На сегодня это все, удачи Вам в освоении языка T-SQL!

Понравилась статья? Поделиться с друзьями:
Заметки IT специалиста
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:
Нажимая на кнопку «Отправить комментарий», я даю согласие на обработку персональных данных и принимаю политику конфиденциальности.