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

Откуда:
Сообщений: 58
Имеется таблица:

DECLARE @t TABLE(c VARCHAR(max))
INSERT INTO @t VALUES('|qaz|234455|0 |31.03.2009|trhth | |')

Требуется получить следующее:
select 'qaz','234455','0 ','31.03.2009','trhth ',' '


Т.е. нужно значения между || поместить в отдельные поля. При условии, что в строке символ "|" встречается очень большое количество раз (здесь приведен кусочек строки).

Можно ли это сделать без курсора?

Заранее спасибо за помощь.
31 авг 10, 16:14    [9357647]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
SET NOCOUNT ON;

DECLARE @T TABLE(ID INT,S VARCHAR(100));
INSERT @T(ID,S) SELECT 1,'|qaz|234455|0 |31.03.2009|trhth | |';

DECLARE @Delimiters VARCHAR(100);
SET @Delimiters='|';

SELECT ID,S
FROM
(
 SELECT T.ID,SUBSTRING(T.S COLLATE Cyrillic_General_CI_AI,V.number,
  (
   SELECT MIN(VV.number)
   FROM master.dbo.spt_values VV JOIN @T TT
   ON TT.ID=T.ID AND VV.type='P' AND VV.number BETWEEN V.number AND LEN(TT.S)+1
   AND SUBSTRING(TT.S+LEFT(@Delimiters,1),VV.number,1) LIKE '['+@Delimiters+']'
  )-V.number
 )
 FROM @T T CROSS JOIN master.dbo.spt_values V
 WHERE V.type='P' AND V.number BETWEEN 1 AND LEN(T.S)+1
 AND SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number,1) LIKE '['+@Delimiters+']'
)T(ID,S)
WHERE S>''
ORDER BY ID,S;
Тааак... Следующий!

https://www.sql.ru/forum/actualthread.aspx?tid=785751#9353872
31 авг 10, 16:23    [9357740]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
ё
Guest
Если,

а где у вас находятся эти строки ? как вы их получаете ?
если это текст.файл, - то не проще ли его импортировать целиком за раз, без распарсивания, создав нужнeю спецификацию...?
31 авг 10, 16:25    [9357766]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
aleks2
Guest
iap
Тааак... Следующий!

https://www.sql.ru/forum/actualthread.aspx?tid=785751#9353872


Халтуру гоните. CTE и номерки - вещь несовместная.

ALTER 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
)
31 авг 10, 16:28    [9357814]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Наверно, для поставленных условий так лучше:
DECLARE @T TABLE(ID INT,S VARCHAR(100));
INSERT @T(ID,S) SELECT 1,'|qaz|234455|0 |31.03.2009|trhth | |';

DECLARE @Delimiters VARCHAR(100);
SET @Delimiters='|';

SELECT ID,number-1 [Pos],S
FROM
(
 SELECT T.ID,V.number, SUBSTRING(T.S COLLATE Cyrillic_General_CI_AI,V.number,
  (
   SELECT MIN(VV.number)
   FROM master.dbo.spt_values VV JOIN @T TT
   ON TT.ID=T.ID AND VV.type='P' AND VV.number BETWEEN V.number AND LEN(TT.S)+1
   AND SUBSTRING(TT.S+LEFT(@Delimiters,1),VV.number,1) LIKE '['+@Delimiters+']'
  )-V.number
 )
 FROM @T T CROSS JOIN master.dbo.spt_values V
 WHERE V.type='P' AND V.number BETWEEN 2 AND LEN(T.S)+1
 AND SUBSTRING(LEFT(@Delimiters,1)+T.S,V.number,1) LIKE '['+@Delimiters+']'
)T(ID,number,S)
ORDER BY ID,number;
31 авг 10, 16:30    [9357847]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
Если
Member

Откуда:
Сообщений: 58
Супер спасибо! =)

Только осталось её повернуть, чтобы эти значения в одной строке но разных столбцах.
31 авг 10, 16:33    [9357872]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iljy
Member

Откуда:
Сообщений: 8711
Если
Только осталось её повернуть, чтобы эти значения в одной строке но разных столбцах.

А зачем? Если у вас заранее неизвестно количество слов - значит будет неизвестно количество полей, а с такой таблицей можно работать только динамическим запросом, оно вам реально надо?
31 авг 10, 16:36    [9357904]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
aleks2
Халтуру гоните. CTE и номерки - вещь несовместная.
Расшифруйте, пожалуйста...
При чём тут CTE? С ним, конечно, тоже можно, но могу же я по-своему предложить?

IMHO, рекурсивное CTE проигрывает постоянной таблице с числами.
31 авг 10, 16:36    [9357908]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
Если
Member

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

да, реально надо.
31 авг 10, 16:42    [9357987]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iljy
Member

Откуда:
Сообщений: 8711
Если
iljy,

да, реально надо.

Ну безумству храбрых. Сохраняйте результат во временную таблицу, генерируйте динамический запрос - и в путь. ROW_NUMBER, PIVOT и FOR XML вам в помощь. Или поиск по форуму (переменное количество столбцов)
31 авг 10, 16:48    [9358056]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
aleks2
Guest
iap
aleks2
Халтуру гоните. CTE и номерки - вещь несовместная.
Расшифруйте, пожалуйста...
При чём тут CTE? С ним, конечно, тоже можно, но могу же я по-своему предложить?

IMHO, рекурсивное CTE проигрывает постоянной таблице с числами.


Данный конкретный случай - единственное полезное применение CTE, известное мне.

Теоретически CTE выигрывает в этой задаче - меньше операций совершается.

кол-во операций
CTE ~ числа разделителей;
NUMBERS ~ числа символов в строке.
31 авг 10, 19:05    [9359254]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: распарсить строку  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
aleks2
...
ALTER 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
)

Мне понравилось!
Заюзал.
Один минус - не работает дальше 100-ой позиции. Ограничение на вложенност/рекурсию CTE.

declare @folio_idsclad_list varchar(100)
 set @Folio_IdSclad_List = '1,2,55,7,dfds,33,,55,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1,6,15,6,6,7,78,9,,0,6,,3,3,3,6,7,8,9,9,0,0,,6,4,3,2,2,22,4,5,6,66, 5,6,7,8,9,0,,2,344555444444444444,4556666,,,,,,,,,,,,77777                ,8' 
select * from dbo.f_StrToTableEx(@Folio_IdSclad_List,',')  where len(value)>0
В Denali CTP3 (RC0 ещё не попробовал) option (maxrecursion 0) в функциях также не доступен.
25 ноя 11, 13:07    [11658201]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
SIMPLicity_
не работает дальше 100-ой позиции
для указания maxrecursion в функции
придется сделать чтобы функция перестала быть инлайновой
25 ноя 11, 13:10    [11658235]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
10589208
25 ноя 11, 13:47    [11658635]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
Maxx
Member [скрыт]

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

сам себя сбаянил
25 ноя 11, 14:37    [11659214]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

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

сам себя сбаянил
Нет! По ссылке - функция!
В противовес aleks2...
25 ноя 11, 14:39    [11659224]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
iap
10589208

Там используется master.dbo.spt_values, причём напрямую - кажется там используется хначение поля number для индекса...
А у мну в нумерации после 2048 идёт дыра и т.д. Не уверен, что это так уж и принципиально (особенно применительно к моей задаче), но тем не менее...

Хочу как-нить "покурить" последние варианты вот отсуда 9688103, типа...
А так таки да, я пользовался и Вашим вариантом, спасибо.
25 ноя 11, 16:09    [11660189]     Ответить | Цитировать Сообщить модератору
 Re: распарсить строку  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
SIMPLicity_,

Вы же понимаете, что master.dbo.spt_values - только для примера?
25 ноя 11, 16:34    [11660472]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить