#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
Опять же, я предполагаю, что у вас есть даты в именах файлов.