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

Откуда:
Сообщений: 184
Доброго времени суток. Имею процедуру где пытаюсь парсить стринг и записать в таблицу :

declare @col1_list varchar(max) , @col2_list varchar(max)
declare @tbl TABLE (col1 int , col2 int)

set @col1_list = '2|6|7|4|3|'
set @col2_list = '1|'

Если в @col1_list будет несколько чисел ,то @col2_list будет только одно число , А также может быть и наоборот.

После парсинга в случае
set @col1_list = '2|6|7|4|3|'
set @col2_list = '1|'


в таблице должны выглядить значения следующим образом :

col1    col2
2          1
6          1
7          1
4          1
3          1

при случае
set @col1_list = '2'
set @col2_list = '1|2|3|4|'

col1    col2
2          1
2          2
2          3
2          4


Сам парсил следующим образом :

declare @col1_list varchar(max) , @col2_list varchar(max)
declare @tbl TABLE (col1 int , col2 int)

set @col1_list = '2|6|7|4|3|'
set @col2_list = '1|'

DECLARE @pos INT = 0
DECLARE @len INT = 0
DECLARE @value varchar(8000)

WHILE CHARINDEX('|', @col1_list, @pos+1)>0
BEGIN
set @len = CHARINDEX('|', @col1_list, @pos+1) - @pos
set @value = SUBSTRING(@col1_list, @pos, @len)
insert into @tbl(col1) values(@value)
set @pos = CHARINDEX('|', @col1_list, @pos+@len) +1
end

select * from @tbl


Никак не придумал как вставить парсер @col2_list. Функция к сожалению не подойдет нужно все сделать в процедуре. Помогите пожалуйста
12 апр 14, 23:37    [15873309]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
RubinDm
Member

Откуда: SPb
Сообщений: 458
NewBie77, вообще t-sql не заточен на parsing. я прикрутил бы табличную clr-функцию. На C# она реализуется прям-таки элементарно. Кроме того, вне зависимости от реализации (tsql/clr), я реализовал бы ее как функцию от одного аргумента - тупо разбор строки в последовательность чисел. Такую функцию можно было бы дернуть дважды (для Ваших двух аргументов), а результаты исполнения (оба результата, т.е. два набора чисел) я поженил бы cross join'ом. Да и вообще в таком виде функция (от одного аргумента) представляется мне более простой и куда более реюзабельной, нежели от двух аргументов.
зы: если clr Вас пугает - дайте знать, я подскажу как оно варится.
13 апр 14, 02:47    [15873722]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
NewBie77
Member

Откуда:
Сообщений: 184
Написал следующим образом :

declare @col1_list varchar(max) , @col2_list varchar(max)
declare @tbl TABLE (col1 int , col2 int)

set @col1_list = '2|6|7|4|3|'
set @col2_list = '1|'

DECLARE @myXML1 AS XML = N'<H><r>' + REPLACE(@col1_list, '|', '</r><r>') + '</r></H>'
DECLARE @myXML2 AS XML = N'<H><r>' + REPLACE(@col2_list, '|', '</r><r>') + '</r></H>';

with mycte as (SELECT Vals1.id.value('.', 'NVARCHAR(50)') AS val1
FROM @myXML1.nodes('/H/r') AS Vals1(id)),
mycte1 as (SELECT Vals2.id.value('.', 'NVARCHAR(50)') AS val2
FROM @myXML2.nodes('/H/r') AS Vals2(id))

insert into @tbl (col1,col2)
select val1,val2
from mycte,mycte1
where val1<>'' and val2<>''

select * from @tbl
13 апр 14, 02:54    [15873744]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
RubinDm
Member

Откуда: SPb
Сообщений: 458
NewBie77, да, тоже вариант.. я тож так делал. правда дороговато, но clr писать (и деплоить) будет чуть дольше (если рука не набита). если никто не смотрит и всем реально пофигу как и чем оно дышит, то нормуль :)
13 апр 14, 03:21    [15873833]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
upor
Member

Откуда:
Сообщений: 11
можно через xml:
declare @col1_list varchar(max) , @col2_list varchar(max)
declare @tbl TABLE (col1 int , col2 int)

set @col1_list = '2|6|7|4|3|'
set @col2_list = '1|'
-----------------------------------------------------------
declare @tmp1 xml
set @tmp1=cast('<r>'+replace(@col1_list,'|', '</r><r>')+'</r>' as xml)
declare @tmp2 xml
set @tmp2=cast('<r>'+replace(@col2_list,'|', '</r><r>')+'</r>' as xml);

with col1 (val, pos)
as
(
select r.value('(.)[1]', 'varchar(max)') val, row_number() over (partition by t.r.value('..', 'int') order by t.r.value('..', 'int') ) pos
  from @tmp1.nodes('/r') t(r)
  where len(r.value('(.)[1]', 'varchar(max)'))>0
),
col2 (val, pos)
as
(
	select r.value('(.)[1]', 'varchar(max)') val, row_number() over (partition by t.r.value('..', 'int') order by t.r.value('..', 'int') ) pos
  from @tmp2.nodes('/r') t(r)
  where len(r.value('(.)[1]', 'varchar(max)'))>0
)
select isnull(col1.val, FIRST_VALUE(col1.val) over ( order by  col1.pos desc)) col1, 
	isnull(col2.val, FIRST_VALUE(col2.val) over ( order by  col2.pos desc)) col2 from col1
full join col2 on col1.pos=col2.pos
order by isnull(col1.pos, col2.pos)
13 апр 14, 10:33    [15874153]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46977
Функция, которая делит строку на слова
13 апр 14, 15:24    [15874848]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
NewBie77
Member

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

К сожалению как я указал в первом посте мне функция не подходила . Написал через XML все заработало на ура
13 апр 14, 20:11    [15875774]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
Glory
Member

Откуда:
Сообщений: 104760
NewBie77
К сожалению как я указал в первом посте мне функция не подходила .

А взять из функции только ее тело не позволила совесть ?
13 апр 14, 20:28    [15875816]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46977
NewBie77
iap,

К сожалению как я указал в первом посте мне функция не подходила . Написал через XML все заработало на ура
А кто говорил про функцию?
Так трудно взять тело функции и применить в любом другом месте?
XML - это тормоз сам по себе.
Поэтому не такое уж громкое ура получается.
13 апр 14, 20:30    [15875824]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
iap
Member

Откуда: Москва
Сообщений: 46977
iap
NewBie77
iap,

К сожалению как я указал в первом посте мне функция не подходила . Написал через XML все заработало на ура
А кто говорил про функцию?
Так трудно взять тело функции и применить в любом другом месте?
XML - это тормоз сам по себе.
Поэтому не такое уж громкое ура получается.
Кстати, а почему табличная инлайн функция не подходит?
В запросе её тело будет подставлено вместо имени функции, а оптимизация проведена потом.
Ничто не мешает использовать функцию в процедуре, если уж требуется именно процедура.
13 апр 14, 20:42    [15875860]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Парсинг стринга и запись в таблицу  [new]
Кесарь
Member

Откуда:
Сообщений: 453
RubinDm
NewBie77, вообще t-sql не заточен на parsing. я прикрутил бы табличную clr-функцию.


Ну конечно, а ещё можно внешнюю программу на С# написать. Чтоб весила не менее 10 мегабайт и столько же занимала в памяти...

Вот мой вариант через рекурсию. И можно примерно так же сделать не для обрубающейся строки, а с передвижным окном.


declare @str varchar(8000) = 'asdewdfw,FREDDY.ascold,PADLO;uuuuutttt2'
declare @sep char(1) = ','


;with cte (strr) as
  (select @str as strr
   union all
   select stuff(cte.strr, 1, (case when charindex (@sep, cte.strr, 1) > 0
                                   then charindex (@sep, cte.strr, 1) else len(cte.strr) end), '')
   from cte
   where cte.strr <> '')
select
 cte.strr,
 substring(cte.strr, 1, (case when charindex (@sep, cte.strr, 1) > 0
                              then charindex (@sep, cte.strr, 1) - 1 else len(cte.strr) end))
from cte
where cte.strr <> ''
option (maxrecursion 5)
7 авг 17, 18:10    [20706326]     Ответить | Цитировать Сообщить модератору
 Re: Парсинг стринга и запись в таблицу  [new]
Кесарь
Member

Откуда:
Сообщений: 453
P.S. "option (maxrecursion 5)" конечно надо закоментить.
7 авг 17, 18:11    [20706332]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить