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

Откуда:
Сообщений: 33
Добрый день.

Как запихнуть это в цикл
delcare ID nvarchar(5)
set @ID = hw001

USE [Hardware]
GO
CREATE TABLE [dbo].[hw] (
           /*@ID int not null*/
	[Page] [varchar](256) NULL,
	[Device] [varchar](256) NULL,
	[Group] [varchar](256) NULL,
	[ItemID] [varchar](10) NULL,
	[Item] [varchar](256) NULL,
	[Value] [varchar](256) NULL
) ON [PRIMARY]
GO
BULK
INSERT [dbo].[hw001] 
FROM '\\192.168.0.10\hw001.csv'
WITH
(
CODEPAGE = '1251',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)

относительно запроса, файлов около 300 нужно запихнуть их в таблицу с идентификатором ID hw*** где *** от 001 до 300
Вопрос как собственно организовать цикл заливки этого всего и как быть с переменной hw*** чтобы она отталкивалась от имени файла, тоесть если файл hw015 то и колонка ID = hw015, плюс если типа затягивать нечего(файлов больше нет) цикл заканчивается.

Зарание спасибо
6 мар 13, 16:43    [14020806]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
Glory
Member

Откуда:
Сообщений: 104751
YeaRmiX
Вопрос как собственно организовать цикл заливки этого всего и как быть с переменной hw*** чтобы она отталкивалась от имени файла, тоесть если файл hw015 то и колонка ID = hw015, плюс если типа затягивать нечего(файлов больше нет) цикл заканчивается.

На каждом шаге цикла добавлять данные сначала в промежуточную таблицу. Которую заапдейтить нужными значениями перед заливкой в основную таблицу
6 мар 13, 16:59    [14020936]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
а как выловить имя файла и вставить его в переменну, insert
6 мар 13, 17:11    [14021043]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Ну есть ещё одно когда я задаю перменную
declare @p nvarchar(256)
set @p = '\\192.168.0.10\ap002.csv'

а потом выполняю
BULK
INSERT [dbo].[temp] FROM '"+@p+"' WITH
(
CODEPAGE = '1251',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)

мне чёта ошибочку выплёвывает
Cannot bulk load. The file "+@p+" does not exist.


плюс если бы я смог организовать с переменной - по идее(я так думаю)
выполнить что то типа RIGHT((LEFT(@p, 16 )),3)
6 мар 13, 19:27    [14021637]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
YeaRmiX
а как выловить имя файла и вставить его в переменну, insert
используйте динамический SQL - формируйте строку с нужным INSERT, потом выполняйте.
6 мар 13, 19:44    [14021682]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
alexeyvg
YeaRmiX
а как выловить имя файла и вставить его в переменну, insert
используйте динамический SQL - формируйте строку с нужным INSERT, потом выполняйте.


ну нифига не понял
6 мар 13, 20:31    [14021819]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
YeaRmiX
alexeyvg
пропущено...
используйте динамический SQL - формируйте строку с нужным INSERT, потом выполняйте.


ну нифига не понял
https://www.sql.ru/faq/faq_topic.aspx?fid=104
6 мар 13, 20:31    [14021820]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Какая то хня с переменными *SCRATCH*
declare @p nvarchar(256), @SQL nvarchar(256), @c nvarchar(4), @f nvarchar(1), @r nvarchar(2) 
set @p = '\\192.168.0.10\hw002.csv'
set @c = '1251'
set @f = ','
set @r = '\n'
set @SQL = 'bulk insert [dbo].[temp] from' + @p + 'with (codepage = '+ @c +', fieldrerminator = '+ @f +', rowterminator = '+ @r +')'
exec (@SQL)

Error
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '\'.


А если так

declare @p nvarchar(256), @SQL nvarchar(256), @c nvarchar(4), @f nvarchar(1), @r nvarchar(2) 
set @p = '\\192.168.0.10\hw002.csv'
set @SQL = 'bulk insert [dbo].[temp] from' + @p + 'with (codepage = '1251', fieldrerminator = ',', rowterminator = '\n')'
exec (@SQL)


то
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '1251'.
7 мар 13, 13:19    [14024317]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Просто кто-то даже не посмотрел на текст команды, которая получилась в переменной.
7 мар 13, 13:25    [14024346]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
ambarka_max
Member

Откуда: Россия
Сообщений: 517
set @SQL = 'bulk insert [dbo].[temp] from ' + QUOTENAME(@p,CHAR(39)) + ' with (codepage = '+ QUOTENAME(@c,CHAR(39)) +', fieldterminator = '+ QUOTENAME(@f,CHAR(39)) +', rowterminator = '+ QUOTENAME(@r,CHAR(39)) +')'
7 мар 13, 13:36    [14024401]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 35374
Блог
это лучше в SSIS делать
7 мар 13, 13:43    [14024432]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
ambarka_max
set @SQL = 'bulk insert [dbo].[temp] from ' + QUOTENAME(@p,CHAR(39)) + ' with (codepage = '+ QUOTENAME(@c,CHAR(39)) +', fieldterminator = '+ QUOTENAME(@f,CHAR(39)) +', rowterminator = '+ QUOTENAME(@r,CHAR(39)) +')'


Спасибо.
7 мар 13, 14:41    [14024789]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
YeaRmiX
Member

Откуда:
Сообщений: 33
Спасибо всем, ниже готовое решение для экспорта кучи CSV файлов в одну таблицу с ИД файла.

IF OBJECT_ID('tempdb..#Path') IS NOT NULL
      DROP TABLE #Path;
IF OBJECT_ID('tempdb..#Content') IS NOT NULL
      DROP TABLE #Content;
IF OBJECT_ID(N'HW') IS NOT NULL
      DROP TABLE HW;

CREATE TABLE HW (
		[Id] [varchar](256) NOT NULL, 
		[Page] [varchar](256) NULL,
		[Device] [varchar](256) NULL,
		[Group] [varchar](256) NULL,
		[ItemID] [varchar](10) NULL,
		[Item] [varchar](256) NULL,
		[Value] [varchar](256) NULL
)
     
DECLARE @filename varchar(256),@path varchar(256)
SET @Path = 'E:\Everest\'

CREATE TABLE #Path (
       id int IDENTITY(1,1)
      ,subdirectory nvarchar(512)
      ,depth int
      ,isfile bit);
INSERT #Path (subdirectory,depth,isfile) EXEC master.sys.xp_dirtree @Path,1,1;


CREATE TABLE #Content (
	[Page] [varchar](256) NULL,
	[Device] [varchar](256) NULL,
	[Group] [varchar](256) NULL,
	[ItemID] [varchar](10) NULL,
	[Item] [varchar](256) NULL,
	[Value] [varchar](256) NULL
)

DECLARE _cursor CURSOR FOR SELECT subdirectory FROM #Path WHERE isfile = 1 AND RIGHT(subdirectory,4) = '.csv' ORDER BY subdirectory;
OPEN _cursor
FETCH NEXT FROM _cursor INTO @filename
WHILE @@FETCH_STATUS = 0
BEGIN

DECLARE @p nvarchar(256), @SQL nvarchar(2000), @c nvarchar(4), @f nvarchar(1), @r nvarchar(2) 
SET @p = '' + @path+@filename + ''
SET @c = '1251'
SET @f = ','
SET @r = '\n'
SET @SQL = 'bulk insert #Content from ' + QUOTENAME(@p,CHAR(39)) + ' with (codepage = '+ QUOTENAME(@c,CHAR(39)) +', fieldterminator = '+ QUOTENAME(@f,CHAR(39)) +', rowterminator = '+ QUOTENAME(@r,CHAR(39)) +')'
EXEC (@SQL)

INSERT INTO HW SELECT LEFT(@filename,5), * FROM #Content

TRUNCATE TABLE #Content;

FETCH NEXT FROM _cursor INTO @filename

END
CLOSE _cursor;
DEALLOCATE _cursor;

TRUNCATE TABLE #Path;
13 мар 13, 12:02    [14044473]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
Виктор_в.ю.
Guest
Как вариант.


CREATE TABLE #Files (FullFilePath VARCHAR (1000) )

--получение списка файлов из указанного каталога и его подкаталагов
INSERT INTO #Files exec master..xp_cmdshell 'DIR "E:\Everest\*.csv" /S /B /A-D'


DECLARE @FILE_NAME VARCHAR(1000)
DECLARE @SQL_CSV VARCHAR(1000)

-- Цикл по таблице #Files, содержащей имена загружаемых файлов
WHILE 1 = 1
BEGIN
SELECT top(1) @FILE_NAME = FullFilePath FROM #Files
IF @@ROWCOUNT = 0 BREAK

-- Командная строка для загрузки текстового файла
set @SQL_CSV ='BULK INSERT dbo.ВАША_ТАБЛИЦА FROM '''+@FILE_NAME+'''
WITH(CODEPAGE = ''RAW'',
FIRSTROW = 1,
FIELDTERMINATOR = '','',
ROWTERMINATOR = ''\n'')'

-- Загрузка текстового файла в таблицу
exec (@SQL_CSV)

-- Удаление строки, содержащей имя загруженного файла из таблицы
DELETE FROM #Files WHERE FullFilePath = @FILE_NAME

END
14 мар 13, 08:45    [14045691]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Bulk insert в цикле  [new]
voter
Member

Откуда:
Сообщений: 21
Виктор_в.ю.
Как вариант.

...
WHILE 1 = 1
BEGIN
...
IF @@ROWCOUNT = 0 BREAK
...
END


Всем привет!

Нашел очень удобный (!) для меня как новичка пример решаемой задачи... но возникла проблема - после выполнения
INSERT INTO #Files exec master..xp_cmdshell 'DIR "C:\MyProjects\Altrade\MOEX\2015\15010*ft.csv" /S /B /A-D'
а таблице появляется дополнительная запись с содержанием Null ... соответственно цикл не прерывается - эта запись остается... подскажите, возможно я что-то неправильно понимаю... заранее признателен...
29 июл 15, 18:15    [17951698]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
voter
таблице появляется дополнительная запись с содержанием Null ... соответственно цикл не прерывается - эта запись остается...
Сразу после INSERT INTO #Files exec master..xp_cmdshell выполните удаление записи с NULL из таблицы #Files
29 июл 15, 18:24    [17951729]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
voter
Member

Откуда:
Сообщений: 21
alexeyvg, спасибо!

Ну т.е. все нормально, так и должно было быть? Если не сложно - откуда дополнительная строка берется?..
29 июл 15, 18:33    [17951753]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
voter
Member

Откуда:
Сообщений: 21
alexeyvg
Сразу после INSERT INTO #Files exec master..xp_cmdshell выполните удаление записи с NULL из таблицы #Files


INSERT INTO #Files exec master..xp_cmdshell 'DIR "C:\MyProjects\Altrade\MOEX\2015\15010*ft.csv" /S /B /A-D'
select * from #Files
DELETE FROM #Files WHERE FullFilePath is null
select * from #Files

... в отладке наглядно видно, что лишняя строчка ушла... первые шаги, сорри... :-)
29 июл 15, 18:45    [17951792]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
voter
Ну т.е. все нормально, так и должно было быть? Если не сложно - откуда дополнительная строка берется?..
Ну как, xp_cmdshell возвращает в виде таблицы все строки, которые посылаются в стандартный поток вывода запускаемыми программами.

А программа (точнее, команда программы CMD) DIR выводит пустую строку в конце. Так уж она устроена.
29 июл 15, 22:23    [17952576]     Ответить | Цитировать Сообщить модератору
 Re: Bulk insert в цикле  [new]
voter
Member

Откуда:
Сообщений: 21
alexeyvg, ясно, спасибо!
29 июл 15, 23:29    [17952825]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить