Как я могу выбрать динамический столбец в инструкции SELECT с помощью OPENROWSET

#sql-server #openrowset

#sql-сервер #openrowset

Вопрос:

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

 SELECT * 
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
                'Excel 8.0;Database=C:PP.xlsx',
                'SELECT * FROM [Daily$]')
  

[введите описание изображения здесь]1

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

Итак, мне нужно решение для выбора столбца = текущая дата (или любая дата). Надеюсь, вы понимаете мою точку зрения, ниже приведен мой код:

 Select 
    t1.*, temp.[13-Nov] as [Plan]
from 
    (select 
         case 
            when FinalMaterial = 'IA15_2020' then 'FADIL'
            when FinalMaterial = 'ID2U_2020' then 'V8'
            when FinalMaterial = 'ID1U_2019' then 'SUV'
            when FinalMaterial = 'ID14_2019' then 'Sedan'
            else FinalMaterial 
         end FinalMaterial,
         case 
            when statusto in ('TP_40', 'TP_40B') then 'Paint' 
            when statusto = 'TP_20' then 'Body'
            when statusto = 'TP_80' then 'OKTS'
            when statusto = 'TP_F1' then 'F1 out'
            else null 
         end Shop,
         count(WorkOrder_NId) Actual
     from 
         vLogicalStatusTrans_1138772611 lo 
     join 
         vWorkOrder_Siemens__1008010152 wo on wo.NId = lo.WorkOrder_NId
     where 
         StatusTo in ('TP_40', 'TP_40B', 'TP_20', 'TP_80', 'TP_F1')
         and dateadd(hh, 7, lo.TransitionTime) >= SMALLDATETIMEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), DAY(GETDATE()), 00, 00)
     group by 
         wo.FinalMaterial, statusto) t1
left join 
    (select * from OPENROWSET('Microsoft.ACE.OLEDB.12.0','Excel 8.0;Database=C:PP.xlsx','SELECT * FROM [Daily$]')) as temp on temp.Model = t1.FinalMaterial and temp.Shop = t1.Shop
where 
    t1.Shop = 'Paint'
  

Ответ №1:

Изменение списка select полей на лету означает создание «динамического запроса», в котором вы создаете весь запрос в строковой переменной ( nvarchar type) и передаете его в хранимую процедуру, например sp_executesql (documentation).

Пример данных

 create table exceldata
(
  id int,
  [14-nov] int,
  [15-nov] int,
  [16-nov] int
);

insert into exceldata (id, [14-nov], [15-nov], [16-nov]) values
(1, 114, 115, 116),
(2, 214, 215, 216);
  

Решение

 declare @today date = getdate();

declare @stmt nvarchar(500) =   'select id, ['
                                replace(convert(nvarchar(6),  @today, 106), ' ', '-')
                                '] from exceldata;'

select @stmt as Statement; -- validation

exec sp_executesql @stmt;
  

Результат

Для @today = '2020-11-14' :

 Statement
-----------------------------------
select id, [14-Nov] from exceldata;

id  14-Nov
--- ------
1   114
2   214
  

Для @today = '2020-11-15' :

 Statement
-----------------------------------
select id, [15-Nov] from exceldata;

id  15-Nov
--- ------
1   115
2   215
  

Скрипка, чтобы увидеть его в действии (включает пошаговое построение формата даты).