Просто чтобы убедиться, что это можно сделать, я придумал решение, которое не работает. Он основан на somebody else's function, чтобы разбить строку на основе разделителя.
Примечание: Для этого требуется, чтобы вы знали максимальную длину токена раньше времени. Функция прекратит возвращать строки, встречая токен дольше указанной длины строки. Вероятно, есть и другие ошибки, поэтому используйте этот код в своей собственной осторожности.
CREATE FUNCTION SplitLines
(
@pString VARCHAR(7999),
@pLineLen INT,
@pDelim CHAR(1)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
WITH
E1(N) AS (--=== Create Ten 1's
SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 --10
),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT N)) FROM E4),
lines AS (
SELECT TOP 1
1 as LineNumber,
ltrim(rtrim(SUBSTRING(@pString, 1, N))) as Line,
N + 1 as start
FROM cteTally
WHERE N <= DATALENGTH(@pString) + 1
AND N <= @pLineLen + 1
AND SUBSTRING(@pString + @pDelim, N, 1) = @pDelim
ORDER BY N DESC
UNION ALL
SELECT LineNumber, Line, start
FROM (
SELECT LineNumber + 1 as LineNumber,
ltrim(rtrim(SUBSTRING(@pString, start, N))) as Line,
start + N + 1 as start,
ROW_NUMBER() OVER (ORDER BY N DESC) as r
FROM cteTally, lines
WHERE N <= DATALENGTH(@pString) + 1 - start
AND N <= @pLineLen
AND SUBSTRING(@pString + @pDelim, start + N, 1) = @pDelim
) A
WHERE r = 1
)
SELECT LineNumber, Line
FROM lines
Это действительно довольно быстро, и вы можете делать крутые вещи, например, присоединиться к нему. Вот простой пример, который получает первую «линию» из каждой строки в таблице:
declare @table table (
id int,
paragraph varchar(7999)
)
insert into @table values (1, '2012-04-24 Change request #3 for the contract per terms and conditions and per John Smith in the PSO department Customer states terms should be Net 60 not Net 30. Please review signed contract for this information.')
insert into @table values (2, 'Is there a way to split a string (from a specific column) to n-number chars without breaking words, with each result in its own row?')
select t.id, l.LineNumber, l.Line, len(Line)
from @table t
cross apply SplitLines(t.paragraph, 42, ' ') l
where l.LineNumber = 1
Самая большая длина? –
Проверьте код PrintMax, который я нашел здесь. , , http://weblogs.asp.net/bdill/archive/2007/09/29/sql-server-print-max.aspx. Он ищет разрывы строк, но вы можете так же легко искать пробелы. –
Взгляните на функцию Split8k Джеффа Модена [здесь] (http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=153458). Вероятно, это может быть изменено, чтобы делать то, что вы хотите. – Chad