Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как загрузить текстовый файл в таблицу  [new]
scorpy
Member

Откуда:
Сообщений: 12
Есть структурированный текстовый файл, поля разделены ";". Формат примерно такой.

Дата-время;штрихкод;поле1; поле2

Фаил периодически выгружается в сетевую папку. Нужно обновить таблицу базы ms sql: найти там поле штрихкода, совпадающее с текстовым файлом и вставить в эту строку таблицы поле1 и поле2.

В каком виде это все можно организовать? Есть ли для этого какие-то "готовые" решения? Подойдут ли для этого утилиты bulc и bcp, или они подходят только для вставки? Как лучше сделать?
17 авг 16, 07:05    [19550452]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить текстовый файл в таблицу  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
OPENROWSET + FORMATFILE
17 авг 16, 07:54    [19550494]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить текстовый файл в таблицу  [new]
aleks2
Guest
-- Description:	Загрузка данных из файлов
-- =============================================
-- exec [Carnival].[LoadDataToTables]  @show = 1
ALTER PROCEDURE [Carnival].[LoadDataToTables] 
  @show bit = 0
AS
BEGIN

SET NOCOUNT ON;

declare @rc int
      , @err int
      , @dT int
      , @time datetime = getdate()
      , @tbl nvarchar(128)
      , @now datetime = getdate();

if @show > 0 begin
    raiserror('LoadDataToTables: запущена...', 0, 1) with nowait;
end;

-- 'TB_SUB_REGION.csv'
if exists( select * from Carnival.Files where ftpfile = 'TB_SUB_REGION.csv' and [new] = 1 ) begin
 
  if @show > 0 begin
    set @dT = datediff(ms, @time, getdate() );
    raiserror('LoadDataToTables: обработка TB_SUB_REGION.csv... dT = %i, rc = %i', 0, 1, @dT, @rc) with nowait;
    set @time = getdate();
   end;

    --if object_id('tempdb.dbo.#TB_SUB_REGION') is not null drop table #TB_SUB_REGION;
    create table #TB_SUB_REGION ( 	dummy varchar(1) NULL,
                                    SUB_REGION_ID int primary key,
	                                SUB_REGION_CODE varchar(4) NOT NULL,
	                                SUB_REGION_NAME varchar(128) NOT NULL,
	                                REGION_ID int NULL,
	                                [STATUS] varchar(32) NOT NULL,
	                                STATUS_DATE varchar(128) NOT NULL,
	                                LAST_ACTIVITY_TYPE char(4) NOT NULL
                                 );

    bulk insert #TB_SUB_REGION
      from 'C:\Gate\In\Atlantis\Carnival\TB_SUB_REGION.csv' 
      with ( FORMATFILE = 'C:\Gate\In\Atlantis\Carnival\TB_SUB_REGION.fmt'
           , DATAFILETYPE = 'char', CODEPAGE = 'RAW', FIRSTROW = 2      
           --, ERRORFILE = 'C:\Gate\In\Atlantis\Carnival\TB_SUB_REGION.err'
           );

/* -- шобы глазками посмотреть результат
      select * from
      openrowset( bulk 'C:\Gate\In\Atlantis\Carnival\TB_SUB_REGION.csv' 
           , FORMATFILE = 'C:\Gate\In\Atlantis\Carnival\TB_SUB_REGION.fmt'
           , CODEPAGE = 'RAW'
           , FIRSTROW = 2      
           ) as x;
*/ 
    if exists( select * from #TB_SUB_REGION ) begin

        with x as ( select    SUB_REGION_ID 
                            , SUB_REGION_CODE
	                        , SUB_REGION_NAME
	                        , REGION_ID 
	                        , [STATUS] 
	                        , STATUS_DATE = convert( datetime, STATUS_DATE, 101 )
	                        , LAST_ACTIVITY_TYPE 
                      from #TB_SUB_REGION
                  )
        merge Carnival.TB_SUB_REGION as t using x  on t.SUB_REGION_ID = x.SUB_REGION_ID
          when not matched by source and t.deleted = 0 then
               update set deleted = 1, updatetime = @now
          when not matched then 
             insert ( SUB_REGION_ID
                    , SUB_REGION_CODE
                    , SUB_REGION_NAME
                    , REGION_ID
                    , STATUS
                    , STATUS_DATE
                    , LAST_ACTIVITY_TYPE
                    , updatetime
                    )
                    values(   x.SUB_REGION_ID
                            , x.SUB_REGION_CODE
                            , x.SUB_REGION_NAME
                            , x.REGION_ID
                            , x.STATUS
                            , x.STATUS_DATE
                            , x.LAST_ACTIVITY_TYPE
                            , @now
                          )
          when matched and ( exists( select   t.SUB_REGION_CODE
                                          , t.SUB_REGION_NAME
                                          , t.REGION_ID
                                          , t.STATUS
                                          , t.STATUS_DATE
                                          , t.LAST_ACTIVITY_TYPE
                                   except
                                   select   x.SUB_REGION_CODE
                                          , x.SUB_REGION_NAME
                                          , x.REGION_ID
                                          , x.STATUS
                                          , x.STATUS_DATE
                                          , x.LAST_ACTIVITY_TYPE
                                 ) or deleted = 1 ) then
              update set  SUB_REGION_CODE = x.SUB_REGION_CODE
                        , SUB_REGION_NAME = x.SUB_REGION_NAME
                        , REGION_ID = x.REGION_ID
                        , [STATUS] = x.STATUS
                        , STATUS_DATE = x.STATUS_DATE
                        , LAST_ACTIVITY_TYPE = x.LAST_ACTIVITY_TYPE
                        , deleted = 0
                        , updatetime = @now
      ;
      set @rc = @@rowcount;
  
      update t set new = 0 from Carnival.Files as t where ftpfile = 'TB_SUB_REGION.csv' and [new] = 1;

   end;

  if @show > 0 begin
    set @dT = datediff(ms, @time, getdate() );
    raiserror('LoadDataToTables: обработка TB_SUB_REGION.csv  закончена. dT = %i, rc = %i', 0, 1, @dT, @rc) with nowait;
    set @time = getdate();
   end;

end; -- if exists( select * from Carnival.Files where ftpfile = 'TB_SUB_REGION.csv' and [new] = 1 )


TB_SUB_REGION.fmt
Тут разделители не ваши, конечно.
11.0
8
1 SQLCHAR 0 1 "\"" 1 DUMMY ""
2 SQLCHAR 0 12 "\",\"" 2 SUB_REGION_ID ""
3 SQLCHAR 0 4 "\",\"" 3 SUB_REGION_CODE Cyrillic_General_CI_AS
4 SQLCHAR 0 128 "\",\"" 4 SUB_REGION_NAME Cyrillic_General_CI_AS
5 SQLCHAR 0 12 "\",\"" 5 REGION_ID ""
6 SQLCHAR 0 32 "\",\"" 6 STATUS Cyrillic_General_CI_AS
7 SQLCHAR 0 24 "\",\"" 7 STATUS_DATE ""
8 SQLCHAR 0 4 "\"\r\n" 8 LAST_ACTIVITY_TYPE Cyrillic_General_CI_AS
17 авг 16, 08:24    [19550533]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить текстовый файл в таблицу  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8815
Напомню, что существует рекомендуемый MS способ импорта данным при помощи Integration Services.
17 авг 16, 13:48    [19552144]     Ответить | Цитировать Сообщить модератору
 Re: Как загрузить текстовый файл в таблицу  [new]
scorpy
Member

Откуда:
Сообщений: 12
Всем спасибо. В общем решил проблему по-свойму, через vbs скрипт, так оказалось проще. Через bulk тоже вроде получилось, но там вылезли свои сложности, имя файла каждый раз будет разное, и файл после загрузки надо как-то помечать или удалять. Ну и кое какую предварительную обработку файла надо было сделать. Может это как-то реализуемо в MS SQL, но сделал как смог... Хоть и не совсем красиво вышло, куча запросов в цикле, но вроде работает.
18 авг 16, 11:38    [19556431]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить