2013-06-12 12 views
5

In MS SQL Server 2012 dispongo di un database con una tabella contenente una colonna varchar contenente un testo che potrebbe includere anche interruzioni di riga.Ottieni il numero di righe per varchar specifico in MS SQL

Esempio di base:

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'); 

Ora voglio ottenere le linee totali di testo per ogni record, vale a dire, qualcosa di simile:

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

Purtroppo, non sembra essere funzioni integrate per qualcosa di simile. La mia idea era di contare le occorrenze Chr(10)+Chr(13) e aggiungere 1 alla fine. Ma CHARINDEX trova solo la prima occorrenza in una stringa.

Qualche idea su come risolvere questo problema?

Ulteriori informazioni che potrebbero essere utili: Per dare una panoramica più approfondita ai miei dati, il "Testo" proviene da una stringa XML che contiene interruzioni di riga, ad es.

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

Io uso CROSS APPLY XML.nodes(... e XPath per trovare tutti <a> nodi del XML. Potrebbe essere risolto direttamente con le funzioni XML T-SQL?

+0

Grazie, già cambiato. L'ho copiato da sqlfiddle.com ma non ero a conoscenza che sono in modalità MySQL – Markus

risposta

7

Utilizzare Replace per eliminare le interruzioni di riga sostituendo con nulla (''). Quindi puoi sottrarre la lunghezza del testo modificato dall'originale.

+0

+1 per la buona risposta. – Devart

+0

Grazie, sembra funzionare bene! – Markus

+0

Come posso contare le righe non vuote? – BlueChippy

4

Prova questo:

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

@ Markus: Questo aiuto? –

+1

+1 per la buona risposta. – Devart

+3

Grazie per la risposta e l'esempio! Funzionando bene! – Markus

6

provare questo -

Query:

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 

uscita:

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

Grazie per il vostro aiuto, LEN() e REPLACE() è ciò di cui avevo bisogno. – Markus

+0

Prego @Markus. – Devart

2

Niente intelligente su questo approccio, e penso che gli esempi che utilizzano sostituire sono più elegante, ma questo è abbastanza cintura e bretelle:

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

Grazie per aver mostrato come implementare il mio primo approccio, questo potrebbe essere utile anche per gli altri che vogliono scrivere la propria funzione. – Markus

Problemi correlati