2013-06-12 17 views
5

W MS SQL Server 2012 mam bazę danych z tabelą zawierającą kolumnę varchar zawierającą tekst, który może zawierać nawet podziały wierszy.Uzyskaj liczbę wierszy dla określonego varcharu w MS SQL

Podstawowe przykład:

CREATE TABLE Example 
(
    [ID] INT 
    , [Text] VARCHAR(100) 
); 

INSERT INTO Example ([ID], [Text]) 
VALUES 
     (1, 'This is a test'), 
     (2, 'This is another 
     test with 
     two line breaks'), 
     (3, 'This is a test 
     with one line break'); 

Teraz chcę uzyskać całkowitą linii tekstu dla każdego rekordu, czyli mniej więcej tak:

-------------------- 
| ID | LinesOfText | 
-------------------- 
| 1 |   1 | 
-------------------- 
| 2 |   3 | 
-------------------- 
| 3 |   2 | 
-------------------- 

Niestety, nie wydaje się być wbudowane funkcje dla czegoś takiego. Mój pomysł polegał na liczeniu wystąpień Chr(10)+Chr(13) i dodaniu 1 na końcu. Ale CHARINDEX znajduje tylko pierwsze wystąpienie w ciągu znaków.

Każdy pomysł, jak rozwiązać ten problem?

Dodatkowe informacje, które mogą być przydatne: Aby uzyskać głębszy wgląd w moje dane, "Tekst" pochodzi z łańcucha XML zawierającego podziały wierszy, np.

... 
<a>This is 
    another test 
    with two line breaks</a> 
... 

używam CROSS APPLY XML.nodes(... i XPath, aby znaleźć wszystkie <a> węzły w XML. Czy można to rozwiązać bezpośrednio za pomocą funkcji T-SQL XML?

+0

Dzięki, już zmienił. Skopiowałem go z sqlfiddle.com, ale nie wiedziałem, że jestem w trybie MySQL – Markus

Odpowiedz

7

Użyj Replace, aby wyeliminować przerwy w linii, zastępując je nic (''). Następnie możesz odjąć długość zmodyfikowanego tekstu od oryginału.

+0

+1, aby uzyskać dobrą odpowiedź. – Devart

+0

Dzięki, wydaje się, że działa dobrze! – Markus

+0

Jak mogę policzyć niepuste linie? – BlueChippy

4

Spróbuj tego:

select id, text,LEN(Text)-LEN(replace(text,char(10),''))+1 LinesOfText 
from Example 
+0

@ Markus: Czy to pomaga? –

+1

+1 za dobrą odpowiedź. – Devart

+3

Dzięki za odpowiedź i przykład! Dobrze pracować! – Markus

6

Spróbuj jeden -

Zapytanie:

DECLARE @XML XML 
SELECT @XML = '<p> 
<a>This is a test</a> 
<a>This is 
    another test 
    with two line breaks</a> 
<a>This is a test 
    with one line break</a> 
</p>' 

SELECT 
     id = ROW_NUMBER() OVER (ORDER BY (SELECT 1)) 
    , LinesOfText = LEN(txt) - LEN(REPLACE(txt, CHAR(10), '')) + 1 
FROM (
    SELECT txt = t.c.value('.', 'VARCHAR(MAX)') 
    FROM @XML.nodes('p/a') t(c) 
) t 

wyjściowa:

id     LinesOfText 
-------------------- -------------------- 
1     1 
2     3 
3     2 
+0

Dzięki za pomoc, LEN() i REPLACE() jest tym, czego potrzebowałem. – Markus

+0

Nie ma za co. @Markus. – Devart

2

Nic mądry o tym podejściem, i myślę, że przykłady wykorzystujące wymienić są bardziej eleganckie, ale jest to dość pas i szelki:

CREATE FUNCTION dbo.fn_LinesOfText(@Text varchar(MAX)) Returns INT As 
Begin 
    Declare @Result int, @LastOffset int 

    SET @LastOffset=0 
    SET @Result=1 
    SET @LastOffset=CHARINDEX(CHAR(10), @Text, @LastOffset) 
    WHILE @LastOffset>=1 BEGIN 
     SET @[email protected]+1 
     SET @LastOffset=CHARINDEX(CHAR(10) ,@Text, @LastOffset+1) 
    END 

    Return @Result 
End 
+1

Dzięki za pokazanie, jak wdrożyć moje pierwsze podejście, może to być również przydatne dla innych, którzy chcą napisać własną funkcję. – Markus

Powiązane problemy