Файл MSSMS — CSV содержит данные, но возвращает NULL с хранимыми процедурами

#sql #sql-server #stored-procedures

#sql #sql-сервер #хранимые процедуры

Вопрос:

Я изо всех сил старался заставить работать код, описанный ниже. Я очень неопытен в MSSMS и SQL. Тем не менее, мне нравится эффективность баз данных SQL, и я бы очень хотел, чтобы этот код работал.

Я протестировал свои CSV-файлы с помощью этого кода:

 BULK INSERT BCPData
FROM 'D:cheesebcp_test.csv'
WITH (FIRSTROW = 2,
      FIELDTERMINATOR = ','
     ,ROWTERMINATOR = '0x0a'
);
GO
  

Они легко импортируются, и данные отображаются.

Однако, если я попытаюсь использовать код, показанный ниже (мне нужен код, который автоматически импортирует несколько файлов CSV в мою таблицу) Я получаю только «НУЛЕВЫЕ» результаты в столбцах.

Мой запрос выглядит следующим образом:

  exec ImportFiles 'd:cheese' , 'd:cheeseArchive' , 'bcp*.csv' , 'MergeBCPData' 
  

Я запускаю этот запрос после использования следующего кода для создания необходимых хранимых процедур:

 if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ImportFiles]') and `OBJECTPROPERTY(id, N'IsProcedure') = 1)`
drop procedure [dbo].[ImportFiles]
GO

create procedure ImportFiles
@FilePath       varchar(1000) = 'd:cheese' ,
@ArchivePath        varchar(1000) = 'd:cheeseArchive' ,
@FileNameMask       varchar(1000) = 'bcp*.csv' ,
@MergeProc      varchar(128) = 'MergeBCPData'

AS

    set nocount on
    
declare @ImportDate datetime
    select @ImportDate = getdate()
    
declare @FileName       varchar(1000) ,
    @File           varchar(1000)

declare @cmd varchar(2000)
    
    create table ##Import (s varchar(8000))
    create table #Dir (s varchar(8000))
    
    /*****************************************************************/
    -- Import file
    /*****************************************************************/
    select  @cmd = 'dir /B '   @FilePath   @FileNameMask
    delete #Dir
    insert #Dir exec master..xp_cmdshell @cmd
    
    delete #Dir where s is null or s like '%not found%'
    while exists (select * from #Dir)
    begin
        select  @FileName = min(s) from #Dir
        select  @File = @FilePath   @FileName
        
        select  @cmd =      'bulk insert'
        select  @cmd = @cmd     ' ##Import' 
        select  @cmd = @cmd     ' from'
        select  @cmd = @cmd     ' '''   replace(@File,'"','')   ''''
        select  @cmd = @cmd     ' with (FIELDTERMINATOR = '','''
        select  @cmd = @cmd     ',ROWTERMINATOR = ''0x0a''
        )'
        
        truncate table ##Import
        
        -- import the data
        exec (@cmd)
                
        -- remove filename just imported
        delete  #Dir where s = @FileName
        
        exec @MergeProc
        
        
        -- Archive the file
        select @cmd = 'move '   @FilePath   @FileName   ' '   @ArchivePath   @FileName
        exec master..xp_cmdshell @cmd
    end
    
    drop table ##Import
    drop table #Dir
go



  if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[MergeBCPData]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[MergeBCPData]
    GO

create procedure MergeBCPData

AS
    set nocount on
    
    -- insert data to production table
    insert  BCPData
        (
        City ,
        Visit_Duration_Seconds ,
        Timezone ,      
        Most_Likely_Company 
        )
    select  
        SUBSTRING('City', 1, 5),
        SUBSTRING('Visit_Duration_Seconds', 1, 12),
        SUBSTRING('Timezone', 1, 3), 
        SUBSTRING('Most_Likely_Company',1, 30)  
    from    ##Import
    
go
  

Любая помощь будет очень признательна. Я надеюсь, что это просто ошибка, которую мои неопытные глаза слишком новы, чтобы уловить. Спасибо!

Комментарии:

1. В вашем процессе таблица импорта MergeBCPData ## даже не существует. Если мне нужно это сделать, я бы сначала вставил все данные из файлов во временную таблицу, а затем в той же процедуре вставил в рабочую таблицу из временной таблицы.

Ответ №1:

Вы заявили: «Мне нужен код, который автоматически импортирует несколько файлов CSV в мою таблицу». Есть ли шаблон в именах файлов, который вы можете использовать? Случайно ли в именах файлов указаны даты? Если есть какой-то повторяющийся шаблон, который вы можете использовать, например, последовательность дат, вы можете перебрать все файлы в своей папке и добавить все файлы в одну таблицу за один раз. Ознакомьтесь с приведенным ниже кодом и отправьте ответ, если у вас есть вопросы.

 DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=50) – we are running 50 loops...change this as needed
BEGIN

PRINT @intFlag


declare @fullpath1 varchar(1000)
select @fullpath1 = '''\your_path_hereFTP'   convert(varchar, getdate()- @intFlag , 112)   '_Daily.csv'''
declare @cmd1 nvarchar(1000)
select @cmd1 = 'bulk insert [dbo].[Daily] from '   @fullpath1   ' with (FIELDTERMINATOR = ''t'', FIRSTROW = 5, ROWTERMINATOR=''0x0a'')'
exec (@cmd1)


SET @intFlag = @intFlag   1
    
END
  

Вот некоторые распространенные форматы дат.

http://www.sql-server-helper.com/tips/date-formats.aspx

Опять же, я предполагаю, что у вас есть даты в именах файлов.