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

Откуда:
Сообщений: 101
Доброго времени суток!

Есть такая задача. Данные в систему поступают в виде потока, который необходимо превратить в таблицу.

В таблице есть столбцы DataFormat и Data. DataFormat содержит по сути заголовки столбцов, разделенные точкой с запятой (;), а в столбце Data содержится сама информация, причем разделенная уже '|' и мало того информация может идти в одной строке как-бы двумя блоками и более, а считываться должна порциями, которые описаны в DataFormat.
Вот пример того, что в подобном поле хранится:
+
DataFormat Data
AdvertiseID;AdvertiseName;GoodsGroup1;GoodsGroup2;GoodsGroup3;GoodsGroup4;GoodsGroup5;GroupDiscID;GroupDiscPercent;GroupDiscSum;GroupDiscTimeBegin;GroupDiscTimeEnd;GroupDiscWeekDays 108|108|10240|0|0|0|0|100663297|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10240|0|0|0|0|100663298|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10240|2|1|1|0|100663299|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|2|0|100663300|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|3|0|100663301|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|4|0|100663302|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|5|0|100663303|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|6|0|100663304|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|7|0|100663305|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|3|0|0|0|100663306|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10241|1|1|1|0|100663307|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|1|0|100663308|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|2|0|100663309|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|2|0|100663310|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|4|0|100663311|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|4|0|100663312|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|5|0|100663313|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|5|0|100663314|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|2|0|0|100663315|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|2|0|0|100663316|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|3|0|0|100663317|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|3|0|0|100663318|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|2|0|0|0|100663319|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|2|0|0|0|100663320|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|3|0|0|0|100663321|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10248|1|0|0|0|100663322|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|1|0|100663323|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|5|0|100663324|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|6|0|100663325|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10241|3|2|2|0|100663326|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|3|2|2|0|100663327|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10248|3|2|4|0|100663328|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|
AdvertiseID;AdvertiseName;GoodsGroup1;GoodsGroup2;GoodsGroup3;GoodsGroup4;GoodsGroup5;GroupDiscID;GroupDiscPercent;GroupDiscSum;GroupDiscTimeBegin;GroupDiscTimeEnd;GroupDiscWeekDays 108|108|10278|3|1|2|0|100663297|30.000000||05.09.2014 00:00|14.09.2014 23:59|0000111|108|108|10278|3|1|3|0|100663298|30.000000||05.09.2014 00:00|14.09.2014 23:59|0000111|108|108|10278|3|2|2|0|100663299|30.000000||05.09.2014 00:00|14.09.2014 23:59|0000111|108|108|10278|3|2|3|0|100663300|30.000000||05.09.2014 00:00|14.09.2014 23:59|0000111|108|108|10241|3|2|2|0|100663331|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10248|3|2|4|0|100663332|20.000000||04.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10240|0|0|0|0|100663301|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10240|0|0|0|0|100663302|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10240|2|1|1|0|100663303|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|2|0|100663304|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|3|0|100663305|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|4|0|100663306|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|5|0|100663307|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|6|0|100663308|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|7|0|100663309|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|3|0|0|0|100663310|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10241|1|1|1|0|100663311|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|1|0|100663312|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|2|0|100663313|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|2|0|100663314|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|4|0|100663315|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|4|0|100663316|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|5|0|100663317|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|5|0|100663318|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|2|0|0|100663319|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|2|0|0|100663320|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|3|0|0|100663321|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|3|0|0|100663322|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|2|0|0|0|100663323|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|2|0|0|0|100663324|30.000000||04.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|3|0|0|0|100663325|20.000000||04.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10248|1|0|0|0|100663326|20.000000||04.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|1|0|100663327|20.000000||04.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|5|0|100663328|20.000000||04.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|6|0|100663329|20.000000||04.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10241|3|2|2|0|100663330|30.000000||04.09.2014 00:00|30.11.2014 07:00|1111111|
16 сен 14, 12:30    [16580301]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
Данные в систему поступают в виде потока,

В какую систему ? Прямо в MSSQL что ли ?
16 сен 14, 12:32    [16580311]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
1. Пишите свой парсер- самое правильное,только на чем нить что не скл
2. Если уж сильно не в моготу - пишите в таблицу и тем же идентитти в виде строки - патом парсите. НО опять при условии ,что данны еидуту строгго по прядку - заголовок -> данные
16 сен 14, 12:34    [16580326]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
Все по порядку идет, но как распарсить я ума не приложу
Вложил скрин ка это выглядит в студии

К сообщению приложен файл. Размер - 8Kb
16 сен 14, 12:47    [16580418]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
но как распарсить я ума не приложу

На данном сайте и в интернете полно примеров парсинга строк с заданным разделителем
16 сен 14, 12:49    [16580433]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
У меня проблема в том, что в Data может быть 1 пакет, описаный в DataFormat но их может быть и 2 и 200, но правда разделителей везде будет одинаковое количество.
16 сен 14, 12:53    [16580472]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
У меня проблема в том, что в Data может быть 1 пакет, описаный в DataFormat но их может быть и 2 и 20

И в чем проблема ?
Вы не можете выбрать "пакет" и распарсить его ?
16 сен 14, 12:56    [16580492]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
Я не знаю как это сделать, поэтому и пишу. Пожалуйста подскажите как я могу это сделать.
16 сен 14, 13:42    [16580797]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
Я не знаю как это сделать, поэтому и пишу.

Мда
Сначала распарсить строку на "пакеты".
Потом пакеты распарситьт на поля.
Потому что у полей и пакетов разные разделители.
А процедура/функция будет одна и та же.
16 сен 14, 13:44    [16580809]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
Подскажите пожалуйста,как я могу распарсить строку на "пакеты", пакетов может быть 1, 2 и 200 а парсить понимаю чт онадо по формату данных DataFormat но как... :(
16 сен 14, 14:04    [16580937]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
Подскажите пожалуйста,как я могу распарсить строку на "пакеты",

Вы ответы читаете ?
Сначала парсите поле с одним разделителем
А потом получившитеся строки парсите с другим раделителем
16 сен 14, 14:06    [16580951]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
aleks2
Guest
Glory
MakPol
Подскажите пожалуйста,как я могу распарсить строку на "пакеты",

Вы ответы читаете ?
Сначала парсите поле с одним разделителем
А потом получившитеся строки парсите с другим раделителем


Вангую, у страдальца ОДИНАКОВЫЙ разделитель.

ЗЫ. Но ничего сложного нема.
16 сен 14, 14:08    [16580964]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
MakPol,

у вас минимум 1 одна проблемма - имена полей есть,а вто размерность данных и сам тип отсутвует .
Как вы будете ето придумывать ?
16 сен 14, 14:10    [16580981]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
aleks2
Guest
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[f_StrToTableEx](@str varchar(8000), @delimiter varchar(64)=',')
returns table as
return(
WITH str_nums ( n1, n2, Number ) 
AS 
( 
select  1-LEN(@delimiter) as n1, charindex(@delimiter, @str+@delimiter) as n2, 0 as Number  
UNION ALL 
select n2 as n1, charindex(@delimiter, @str+@delimiter, n2+LEN(@delimiter)) as n2, Number+1 as Number
from str_nums
WHERE n2<len(@str)
) 
SELECT SUBSTRING(@str, n1+LEN(@delimiter), n2-n1-1) as Value, Number, n1+1 as StartPosition FROM str_nums
)
GO

declare @fm varchar(1024) = 'AdvertiseID;AdvertiseName;GoodsGroup1;GoodsGroup2;GoodsGroup3;GoodsGroup4;GoodsGroup5;GroupDiscID;GroupDiscPercent;GroupDiscSum;GroupDiscTimeBegin;GroupDiscTimeEnd;GroupDiscWeekDays'

declare @dt varchar(8000) = '108|108|10240|0|0|0|0|100663297|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10240|0|0|0|0|100663298|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10240|2|1|1|0|100663299|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|2|0|100663300|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|3|0|100663301|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|4|0|100663302|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|5|0|100663303|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|6|0|100663304|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|2|1|7|0|100663305|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10240|3|0|0|0|100663306|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10241|1|1|1|0|100663307|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|1|0|100663308|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|2|0|100663309|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|2|0|100663310|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|4|0|100663311|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|4|0|100663312|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|1|5|0|100663313|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|1|5|0|100663314|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|2|0|0|100663315|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|2|0|0|100663316|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|1|3|0|0|100663317|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|1|3|0|0|100663318|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|2|0|0|0|100663319|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|2|0|0|0|100663320|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10241|3|0|0|0|100663321|20.000000||03.09.2014 09:00|11.09.2014 10:00|1111111|108|108|10248|1|0|0|0|100663322|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|1|0|100663323|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|5|0|100663324|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10248|3|1|6|0|100663325|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111|108|108|10241|3|2|2|0|100663326|30.000000||03.09.2014 00:00|30.11.2014 07:00|1111111|108|108|10241|3|2|2|0|100663327|30.000000||03.09.2014 22:00|30.11.2014 23:59|1111111|108|108|10248|3|2|4|0|100663328|20.000000||03.09.2014 00:00|01.10.2014 23:59|1111111'

select d.Number/( select count(*) from dbo.f_StrToTableEx(@fm, ';') ) as GroupNumber
      , f.Value as Name, d.Value as Data
  from dbo.f_StrToTableEx(@fm, ';') as f
       inner join dbo.f_StrToTableEx(@dt, '|') as d
       on f.Number = d.Number%( select count(*) from dbo.f_StrToTableEx(@fm, ';') ) 
  order by d.Number
  option( MAXRECURSION 0 );
  
16 сен 14, 14:26    [16581090]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
Ого, спасибо огромное!!!
Теперь привести все к столбцам и можно в таблицу все вытаскивать. Ну точнее, чтобы то что в DataFormat стало столбцами, а то что в Data парсилось как строки, только добавлялся GroupNumber.
Т.е. получается из картинки в топике
должно получиться что-то вроде
Date_SendPosAdvertiseIDAdvertiseNameGoodsGroup1GoodsGroup2GoodsGroup3GoodsGroup4GoodsGroup5GroupDiscIDGroupDiscPercentGroupDiscSumGroupDiscTimeBeginGroupDiscTimeEndGroupDiscWeekDays
03.09.2014 0:33110810810240000010066329730.00000003.09.2014 0:0030.11.2014 7:001111111
03.09.2014 0:33210810810240000010066329830.00000003.09.2014 22:0030.11.2014 23:591111111
03.09.2014 0:33310810810240211010066329920.00000003.09.2014 9:0011.09.2014 10:001111111
03.09.2014 0:33..........................................
04.09.2014 0:31110810810278312010066329730.00000005.09.2014 0:0014.09.2014 23:590000111
04.09.2014 0:31210810810278313010066329830.00000005.09.2014 0:0014.09.2014 23:590000111
04.09.2014 0:31..........................................
04.09.2014 0:313610810810241322010066333030.00000004.09.2014 0:0030.11.2014 7:001111111
16 сен 14, 15:10    [16581439]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
Само изображение

К сообщению приложен файл. Размер - 9Kb
16 сен 14, 15:12    [16581449]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
aleks2
Guest
MakPol
должно получиться что-то вроде

Дарагой, нечищеная рыба?
Сам то пошевели извилиной, али совсем ее нету?
16 сен 14, 15:46    [16581670]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
aleks2
Дарагой, нечищеная рыба?
Сам то пошевели извилиной, али совсем ее нету?

Да вроде что-то было, орешек от уха до уха на веревочке болтался. Хотя когда код увидел, понял, что орешек то похоже подсох.
Еще раз большое спасибо за код!
16 сен 14, 15:53    [16581719]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
MakPol
должно получиться что-то вроде

1. Выгрузи содержимое DataFormat+ Data в текстовые файлы
2. Сделай linked server к каталогу с этми файлами
3. делай select-ы к linked server-у
16 сен 14, 15:55    [16581732]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
aleks2
Guest
Glory
MakPol
должно получиться что-то вроде

1. Выгрузи содержимое DataFormat+ Data в текстовые файлы
2. Сделай linked server к каталогу с этми файлами
3. делай select-ы к linked server-у

1. Не, долго и не по силам ТС.
2. Лучше его PIVOT-у научи.

ЗЫ. В реальности тредстартеру это не надо.
Если там постоянный список заголовков - нафига список заголовков.
Если у него переменный список заголовков - в какие такие таблицы он собрался складывать?
16 сен 14, 16:07    [16581810]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
MakPol
Member

Откуда:
Сообщений: 101
PIVOT-у учить не надо, большое спасибо!
16 сен 14, 16:22    [16581895]     Ответить | Цитировать Сообщить модератору
 Re: Необходима помощь в разборе строки  [new]
Glory
Member

Откуда:
Сообщений: 104760
aleks2
1. Не, долго

Дольше парсинга и pivot-а ?
16 сен 14, 16:37    [16581983]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить