Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
MakPol Member Откуда: Сообщений: 101 |
Доброго времени суток! Есть такая задача. Данные в систему поступают в виде потока, который необходимо превратить в таблицу. В таблице есть столбцы DataFormat и Data. DataFormat содержит по сути заголовки столбцов, разделенные точкой с запятой (;), а в столбце Data содержится сама информация, причем разделенная уже '|' и мало того информация может идти в одной строке как-бы двумя блоками и более, а считываться должна порциями, которые описаны в DataFormat. Вот пример того, что в подобном поле хранится:
|
|
16 сен 14, 12:30 [16580301] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
В какую систему ? Прямо в MSSQL что ли ? |
||
16 сен 14, 12:32 [16580311] Ответить | Цитировать Сообщить модератору |
Maxx Member [скрыт] Откуда: Сообщений: 24290 |
1. Пишите свой парсер- самое правильное,только на чем нить что не скл 2. Если уж сильно не в моготу - пишите в таблицу и тем же идентитти в виде строки - патом парсите. НО опять при условии ,что данны еидуту строгго по прядку - заголовок -> данные |
16 сен 14, 12:34 [16580326] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Все по порядку идет, но как распарсить я ума не приложу Вложил скрин ка это выглядит в студии К сообщению приложен файл. Размер - 8Kb |
16 сен 14, 12:47 [16580418] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
На данном сайте и в интернете полно примеров парсинга строк с заданным разделителем |
||
16 сен 14, 12:49 [16580433] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
У меня проблема в том, что в Data может быть 1 пакет, описаный в DataFormat но их может быть и 2 и 200, но правда разделителей везде будет одинаковое количество. |
16 сен 14, 12:53 [16580472] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
И в чем проблема ? Вы не можете выбрать "пакет" и распарсить его ? |
||
16 сен 14, 12:56 [16580492] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Я не знаю как это сделать, поэтому и пишу. Пожалуйста подскажите как я могу это сделать. |
16 сен 14, 13:42 [16580797] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Мда Сначала распарсить строку на "пакеты". Потом пакеты распарситьт на поля. Потому что у полей и пакетов разные разделители. А процедура/функция будет одна и та же. |
||
16 сен 14, 13:44 [16580809] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Подскажите пожалуйста,как я могу распарсить строку на "пакеты", пакетов может быть 1, 2 и 200 а парсить понимаю чт онадо по формату данных DataFormat но как... :( |
16 сен 14, 14:04 [16580937] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Вы ответы читаете ? Сначала парсите поле с одним разделителем А потом получившитеся строки парсите с другим раделителем |
||
16 сен 14, 14:06 [16580951] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Вангую, у страдальца ОДИНАКОВЫЙ разделитель. ЗЫ. Но ничего сложного нема. |
||||
16 сен 14, 14:08 [16580964] Ответить | Цитировать Сообщить модератору |
Maxx Member [скрыт] Откуда: Сообщений: 24290 |
MakPol, у вас минимум 1 одна проблемма - имена полей есть,а вто размерность данных и сам тип отсутвует . Как вы будете ето придумывать ? |
16 сен 14, 14:10 [16580981] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Ого, спасибо огромное!!! Теперь привести все к столбцам и можно в таблицу все вытаскивать. Ну точнее, чтобы то что в DataFormat стало столбцами, а то что в Data парсилось как строки, только добавлялся GroupNumber. Т.е. получается из картинки в топике должно получиться что-то вроде
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
16 сен 14, 15:10 [16581439] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Само изображение К сообщению приложен файл. Размер - 9Kb |
16 сен 14, 15:12 [16581449] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Дарагой, нечищеная рыба? Сам то пошевели извилиной, али совсем ее нету? |
||
16 сен 14, 15:46 [16581670] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
Да вроде что-то было, орешек от уха до уха на веревочке болтался. Хотя когда код увидел, понял, что орешек то похоже подсох. Еще раз большое спасибо за код! |
||
16 сен 14, 15:53 [16581719] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
1. Выгрузи содержимое DataFormat+ Data в текстовые файлы 2. Сделай linked server к каталогу с этми файлами 3. делай select-ы к linked server-у |
||
16 сен 14, 15:55 [16581732] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
1. Не, долго и не по силам ТС. 2. Лучше его PIVOT-у научи. ЗЫ. В реальности тредстартеру это не надо. Если там постоянный список заголовков - нафига список заголовков. Если у него переменный список заголовков - в какие такие таблицы он собрался складывать? |
||||
16 сен 14, 16:07 [16581810] Ответить | Цитировать Сообщить модератору |
MakPol Member Откуда: Сообщений: 101 |
PIVOT-у учить не надо, большое спасибо! |
16 сен 14, 16:22 [16581895] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Дольше парсинга и pivot-а ? |
||
16 сен 14, 16:37 [16581983] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |